package protobuf.codec; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.util.Map; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.Message; import com.google.protobuf.UnknownFieldSet; /** * Protobuf codec. * Please read the codec implementation for exact details on features like support for unknownfields , print formats etc. * @author sijuv * */ public interface Codec { /** * The default element name that the for the field in the response/input which contains * the unknown fields. This element name can be overridden with the value set to the * feature {@link Feature#UNKNOWN_FIELD_ELEM_NAME} */ public static final String DEFAULT_UNKNOWN_FIELD_ELEM_NAME = "unknownfields"; /** * The default prefix to be used for extension fields. The value of this field can be controlled by the * feature {@link Feature#EXTENSION_FIELD_NAME_PREFIX}. The name of the extension field will be the value that this feature gives * appended by "-<fieldname>" */ public static final String DEFAULT_EXTENSION_NAME_PREFIX = "extension"; /** * Write this Message {@link Message} to the provided output stream. The underlying stream is not closed by default, * user {@link Feature#CLOSE_STREAM} for the required settings. * The default values are not written out, the reason being that the client should be aware of the protobuf schema. * The {@link UnknownFieldSet} are written out on whether the {@link Feature#UNKNOWN_FIELD_ELEM_NAME} is set. By default, {@link UnknownFieldSet} * is written out Check the codec implementation on how the unknown field set is written out. * Extension fields are written out and the naming depends on the {@link Feature#EXTENSION_FIELD_NAME_PREFIX} set. * If an extension field not provided in the registry is encountered that field is skipped. * @param message the {@link Message} * @param writer the output stream writer * @throws IOException * @throws IllegalArgumentException if the provided message is not initialized */ void fromMessage(Message message, Writer writer) throws IOException; /** * Create a {@link Message} off the provided input stream.The underlying stream is not closed by default, * user {@link Feature#CLOSE_STREAM} for the required settings. * In case null values encountered are skipped since protobuf does not support null values yet * ( http://code.google.com/p/protobuf/issues/detail?id=57 ) * The default values are not written out, the reason being that the client should be aware of the protobuf schema. * The {@link UnknownFieldSet} are read in depending on whether the {@link Feature#UNKNOWN_FIELD_ELEM_NAME} is set. By default, {@link UnknownFieldSet} * is read in. Check the codec implementation on how the unknown field need to be passed in. * Extension field names depend on {@link Feature#EXTENSION_FIELD_NAME_PREFIX} * If an extension field not provided in the registry is encountered that field is skipped. * @param messageType the {@link Class} corresponding to the {@link Message} the stream needs to be read into * @param reader the input stream reader * @return the {@link Message} * @throws IOException */ <T extends Message> T toMessage(Class<T> messageType, Reader reader) throws IOException; /** * Create a {@link Message} off the provided input stream.The underlying stream is not closed by default, * user {@link Feature#CLOSE_STREAM} for the required settings. * In case null values encountered are skipped since protobuf does not support null values yet * ( http://code.google.com/p/protobuf/issues/detail?id=57 ) * Extension fields looked up from the provided extension registry, if a field from the provided stream * is identified to be an extension field, but a corresponding mapping is not found in the registry, then * the field is skipped. * @param messageType the {@link Class} corresponding to the {@link Message} the stream needs to be read into * @param reader the input stream reader * @param extnRegistry the extension registry which contains the defn for extension fields. * @return the {@link Message} * @throws IOException */ <T extends Message> T toMessage(Class<T> messageType, Reader reader, ExtensionRegistry extnRegistry) throws IOException; /** * Write the message to the stream, uses UTF8 as the charset * @param message * @param os * @throws IOException * @see {@link #fromMessage(Message, Writer)} */ void fromMessage(Message message, OutputStream os) throws IOException; /** * Read the message from the stream, uses UTF8 as the charset encoding. * @param messageType the {@link Class} corresponding to the {@link Message} the stream needs to be read into * @param in * @return * @throws IOException * @see {@link #toMessage(Class, Reader)} */ <T extends Message> T toMessage(Class<T> messageType, InputStream in) throws IOException; /** * Read the message from the stream, uses UTF8 as the charset encoding. * @param messageType the {@link Class} corresponding to the {@link Message} the stream needs to be read into * @param in * @param extnRegistry the extension registry * @return * @throws IOException * @see {@link #toMessage(Class, Reader)} */ <T extends Message> T toMessage(Class<T> messageType, InputStream in, ExtensionRegistry extnRegistry) throws IOException; /** * Set a codec feature, * @param feature the feature * @param value the feature value. * @throws IllegalArgumentException in case the codec does not support the provided feature * in case the value is not applicable for the feature */ void setFeature(Feature feature, Object value); /** * Get the value this feature is set to. * @param feature the feature * @return the value this feature is set to. */ Object getFeature(Feature feature); /** * Indicates whether this feature is set on the codec. * @param feature the feature * @return <code>true</code> if feature is set, <code>false</code> otherwise */ boolean isFeatureSet(Feature feature); /** * Returns an unmodifiable map containing all features and the values they are set to. * @return */ Map<Feature, Object> getAllFeaturesSet(); /** * Features supported by the codec. * @author sijuv * */ public enum Feature { /** Pretty print **/ PRETTY_PRINT, /** Close the underlying stream */ CLOSE_STREAM, /** Support unknown fields */ SUPPORT_UNKNOWN_FIELDS, /** Unknown field element name */ UNKNOWN_FIELD_ELEM_NAME, /** Extension field name prefix */ EXTENSION_FIELD_NAME_PREFIX, /** Strip leading and trailing underscores from field names */ STRIP_FIELD_NAME_UNDERSCORES, /** Provide field name substitutes for reading and writing from/to a protobuf stream*/ FIELD_NAME_READ_SUBSTITUTES, FIELD_NAME_WRITE_SUBSTITUTES; } }