You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2009/02/17 15:49:53 UTC
svn commit: r745108 [1/2] - in
/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf:
./ compiler/
Author: chirino
Date: Tue Feb 17 14:49:52 2009
New Revision: 745108
URL: http://svn.apache.org/viewvc?rev=745108&view=rev
Log:
Added a new alternative java generator which uses a different API style than the current one. The new API style should
make it easier to work with deffered demarshalled messages.
Added:
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBuffer.java
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBufferSupport.java
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/CompilerException.java
Modified:
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ProtoMojo.java
Modified: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java?rev=745108&r1=745107&r2=745108&view=diff
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java (original)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java Tue Feb 17 14:49:52 2009
@@ -357,6 +357,9 @@
* The end of the stream or the current limit was reached.
*/
public Buffer readRawBytes(int size) throws IOException {
+ if( size == 0) {
+ return new Buffer(new byte[]{});
+ }
if( this.pos+size > limit ) {
throw new EOFException();
}
Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBuffer.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBuffer.java?rev=745108&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBuffer.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBuffer.java Tue Feb 17 14:49:52 2009
@@ -0,0 +1,28 @@
+package org.apache.activemq.protobuf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public interface MessageBuffer {
+
+ public int serializedSizeUnframed();
+
+ public int serializedSizeFramed();
+
+ public Buffer toUnframedBuffer();
+
+ public Buffer toFramedBuffer();
+
+ public byte[] toUnframedByteArray();
+
+ public byte[] toFramedByteArray();
+
+ public void writeUnframed(CodedOutputStream output) throws java.io.IOException;
+
+ public void writeFramed(CodedOutputStream output) throws java.io.IOException;
+
+ public void writeUnframed(OutputStream output) throws IOException;
+
+ public void writeFramed(OutputStream output) throws java.io.IOException;
+
+}
Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBufferSupport.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBufferSupport.java?rev=745108&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBufferSupport.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/MessageBufferSupport.java Tue Feb 17 14:49:52 2009
@@ -0,0 +1,128 @@
+package org.apache.activemq.protobuf;
+
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+
+final public class MessageBufferSupport {
+
+ public static final String FORZEN_ERROR_MESSAGE = "Modification not allowed after object has been fozen. Try modifying a copy of this object.";
+
+ static public Buffer toUnframedBuffer(MessageBuffer message) {
+ try {
+ int size = message.serializedSizeUnframed();
+ BufferOutputStream baos = new BufferOutputStream(size);
+ CodedOutputStream output = new CodedOutputStream(baos);
+ message.writeUnframed(output);
+ Buffer rc = baos.toBuffer();
+ if( rc.length != size ) {
+ throw new IllegalStateException("Did not write as much data as expected.");
+ }
+ return rc;
+ } catch (IOException e) {
+ throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
+ }
+ }
+
+ static public Buffer toFramedBuffer(MessageBuffer message) {
+ try {
+ int size = message.serializedSizeFramed();
+ BufferOutputStream baos = new BufferOutputStream(size);
+ CodedOutputStream output = new CodedOutputStream(baos);
+ message.writeFramed(output);
+ Buffer rc = baos.toBuffer();
+ if( rc.length != size ) {
+ throw new IllegalStateException("Did not write as much data as expected.");
+ }
+ return rc;
+ } catch (IOException e) {
+ throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
+ }
+ }
+
+ public static void writeMessage(CodedOutputStream output, int tag, MessageBuffer message) throws IOException {
+ output.writeTag(tag, WIRETYPE_LENGTH_DELIMITED);
+ message.writeFramed(output);
+ }
+
+ public static int computeMessageSize(int tag, MessageBuffer message) {
+ return CodedOutputStream.computeTagSize(tag) + message.serializedSizeFramed();
+ }
+
+ public static Buffer readFrame(java.io.InputStream input) throws IOException {
+ int length = readRawVarint32(input);
+ byte[] data = new byte[length];
+ int pos = 0;
+ while (pos < length) {
+ int r = input.read(data, pos, length - pos);
+ if (r < 0) {
+ throw new InvalidProtocolBufferException("Input stream ended before a full message frame could be read.");
+ }
+ pos += r;
+ }
+ return new Buffer(data);
+ }
+
+ /**
+ * Read a raw Varint from the stream. If larger than 32 bits, discard the
+ * upper bits.
+ */
+ static public int readRawVarint32(InputStream is) throws IOException {
+ byte tmp = readRawByte(is);
+ if (tmp >= 0) {
+ return tmp;
+ }
+ int result = tmp & 0x7f;
+ if ((tmp = readRawByte(is)) >= 0) {
+ result |= tmp << 7;
+ } else {
+ result |= (tmp & 0x7f) << 7;
+ if ((tmp = readRawByte(is)) >= 0) {
+ result |= tmp << 14;
+ } else {
+ result |= (tmp & 0x7f) << 14;
+ if ((tmp = readRawByte(is)) >= 0) {
+ result |= tmp << 21;
+ } else {
+ result |= (tmp & 0x7f) << 21;
+ result |= (tmp = readRawByte(is)) << 28;
+ if (tmp < 0) {
+ // Discard upper 32 bits.
+ for (int i = 0; i < 5; i++) {
+ if (readRawByte(is) >= 0)
+ return result;
+ }
+ throw new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ static public byte readRawByte(InputStream is) throws IOException {
+ int rc = is.read();
+ if (rc == -1) {
+ throw new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
+ + "misreported its own length.");
+ }
+ return (byte) rc;
+ }
+
+ static public <T> void addAll(Iterable<T> values, Collection<? super T> list) {
+ if (values instanceof Collection) {
+ @SuppressWarnings("unsafe")
+ Collection<T> collection = (Collection<T>) values;
+ list.addAll(collection);
+ } else {
+ for (T value : values) {
+ list.add(value);
+ }
+ }
+ }
+
+
+}
Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java?rev=745108&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java Tue Feb 17 14:49:52 2009
@@ -0,0 +1,2062 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.protobuf.compiler;
+
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED32;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED64;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_VARINT;
+import static org.apache.activemq.protobuf.WireFormat.makeTag;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.activemq.protobuf.compiler.parser.ParseException;
+import org.apache.activemq.protobuf.compiler.parser.ProtoParser;
+
+public class AltJavaGenerator {
+
+ private File out = new File(".");
+ private File[] path = new File[]{new File(".")};
+
+ private ProtoDescriptor proto;
+ private String javaPackage;
+ private String outerClassName;
+ private PrintWriter w;
+ private int indent;
+ private ArrayList<String> errors = new ArrayList<String>();
+ private boolean multipleFiles;
+ private boolean auto_clear_optional_fields;
+
+ public static void main(String[] args) {
+
+ AltJavaGenerator generator = new AltJavaGenerator();
+ args = CommandLineSupport.setOptions(generator, args);
+
+ if (args.length == 0) {
+ System.out.println("No proto files specified.");
+ }
+ for (int i = 0; i < args.length; i++) {
+ try {
+ System.out.println("Compiling: "+args[i]);
+ generator.compile(new File(args[i]));
+ } catch (CompilerException e) {
+ System.out.println("Protocol Buffer Compiler failed with the following error(s):");
+ for (String error : e.getErrors() ) {
+ System.out.println("");
+ System.out.println(error);
+ }
+ System.out.println("");
+ System.out.println("Compile failed. For more details see error messages listed above.");
+ return;
+ }
+ }
+
+ }
+
+ interface Closure {
+ void execute() throws CompilerException;
+ }
+
+ public void compile(File file) throws CompilerException {
+
+ // Parse the proto file
+ FileInputStream is=null;
+ try {
+ is = new FileInputStream(file);
+ ProtoParser parser = new ProtoParser(is);
+ proto = parser.ProtoDescriptor();
+ proto.setName(file.getName());
+ loadImports(proto, file.getParentFile());
+ proto.validate(errors);
+ } catch (FileNotFoundException e) {
+ errors.add("Failed to open: "+file.getPath()+":"+e.getMessage());
+ } catch (ParseException e) {
+ errors.add("Failed to parse: "+file.getPath()+":"+e.getMessage());
+ } finally {
+ try { is.close(); } catch (Throwable ignore){}
+ }
+
+ if (!errors.isEmpty()) {
+ throw new CompilerException(errors);
+ }
+
+ // Load the options..
+ javaPackage = javaPackage(proto);
+ outerClassName = javaClassName(proto);
+// optimizeFor = getOption(proto.getOptions(), "optimize_for", "SPEED");
+ multipleFiles = isMultipleFilesEnabled(proto);
+// deferredDecode = Boolean.parseBoolean(getOption(proto.getOptions(), "deferred_decode", "false"));
+ auto_clear_optional_fields = Boolean.parseBoolean(getOption(proto.getOptions(), "auto_clear_optional_fields", "false"));
+
+ if( multipleFiles ) {
+ generateProtoFile();
+ } else {
+ writeFile(outerClassName, new Closure(){
+ public void execute() throws CompilerException {
+ generateProtoFile();
+ }
+ });
+ }
+
+ if (!errors.isEmpty()) {
+ throw new CompilerException(errors);
+ }
+
+ }
+
+ private void writeFile(String className, Closure closure) throws CompilerException {
+ PrintWriter oldWriter = w;
+ // Figure out the java file name..
+ File outputFile = out;
+ if (javaPackage != null) {
+ String packagePath = javaPackage.replace('.', '/');
+ outputFile = new File(outputFile, packagePath);
+ }
+ outputFile = new File(outputFile, className + ".java");
+
+ // Start writing the output file..
+ outputFile.getParentFile().mkdirs();
+
+ FileOutputStream fos=null;
+ try {
+ fos = new FileOutputStream(outputFile);
+ w = new PrintWriter(fos);
+ closure.execute();
+ w.flush();
+ } catch (FileNotFoundException e) {
+ errors.add("Failed to write to: "+outputFile.getPath()+":"+e.getMessage());
+ } finally {
+ try { fos.close(); } catch (Throwable ignore){}
+ w = oldWriter;
+ }
+ }
+
+ private void loadImports(ProtoDescriptor proto, File protoDir) {
+ LinkedHashMap<String,ProtoDescriptor> children = new LinkedHashMap<String,ProtoDescriptor>();
+ for (String imp : proto.getImports()) {
+ File file = new File(protoDir, imp);
+ for (int i = 0; i < path.length && !file.exists(); i++) {
+ file = new File(path[i], imp);
+ }
+ if ( !file.exists() ) {
+ errors.add("Cannot load import: "+imp);
+ }
+
+ FileInputStream is=null;
+ try {
+ is = new FileInputStream(file);
+ ProtoParser parser = new ProtoParser(is);
+ ProtoDescriptor child = parser.ProtoDescriptor();
+ child.setName(file.getName());
+ loadImports(child, file.getParentFile());
+ children.put(imp, child);
+ } catch (ParseException e) {
+ errors.add("Failed to parse: "+file.getPath()+":"+e.getMessage());
+ } catch (FileNotFoundException e) {
+ errors.add("Failed to open: "+file.getPath()+":"+e.getMessage());
+ } finally {
+ try { is.close(); } catch (Throwable ignore){}
+ }
+ }
+ proto.setImportProtoDescriptors(children);
+ }
+
+
+ private void generateProtoFile() throws CompilerException {
+ if( multipleFiles ) {
+ for (EnumDescriptor value : proto.getEnums().values()) {
+ final EnumDescriptor o = value;
+ String className = uCamel(o.getName());
+ writeFile(className, new Closure(){
+ public void execute() throws CompilerException {
+ generateFileHeader();
+ generateEnum(o);
+ }
+ });
+ }
+ for (MessageDescriptor value : proto.getMessages().values()) {
+ final MessageDescriptor o = value;
+ String className = uCamel(o.getName());
+ writeFile(className, new Closure(){
+ public void execute() throws CompilerException {
+ generateFileHeader();
+ generateMessageBean(o);
+ }
+ });
+ }
+
+ } else {
+ generateFileHeader();
+
+ p("public class " + outerClassName + " {");
+ indent();
+
+ for (EnumDescriptor enumType : proto.getEnums().values()) {
+ generateEnum(enumType);
+ }
+ for (MessageDescriptor m : proto.getMessages().values()) {
+ generateMessageBean(m);
+ }
+
+ unindent();
+ p("}");
+ }
+ }
+
+ private void generateFileHeader() {
+ p("//");
+ p("// Generated by protoc, do not edit by hand.");
+ p("//");
+ if (javaPackage != null) {
+ p("package " + javaPackage + ";");
+ p("");
+ }
+ }
+
+ private void generateMessageBean(MessageDescriptor m) {
+
+ String className = uCamel(m.getName());
+ String beanClassName = className+"Bean";
+ String bufferClassName = className+"Buffer";
+ p();
+
+ String staticOption = "static ";
+ if( multipleFiles && m.getParent()==null ) {
+ staticOption="";
+ }
+
+ p(staticOption+"public interface " + className +" {");
+ p();
+ indent();
+
+ for (EnumDescriptor enumType : m.getEnums().values()) {
+ generateEnum(enumType);
+ }
+
+ // Generate the Nested Messages.
+ for (MessageDescriptor subMessage : m.getMessages().values()) {
+ generateMessageBean(subMessage);
+ }
+
+ // Generate the Group Messages
+ for (FieldDescriptor field : m.getFields().values()) {
+ if( field.isGroup() ) {
+ generateMessageBean(field.getGroup());
+ }
+ }
+
+ // Generate the field getters
+ for (FieldDescriptor field : m.getFields().values()) {
+ generateFieldGetterSignatures(field);
+ }
+
+ p("public "+beanClassName+" copy();");
+ p("public "+bufferClassName+" freeze();");
+ p("public java.lang.StringBuilder toString(java.lang.StringBuilder sb, String prefix);");
+
+
+ p();
+ p("static public final class "+beanClassName+" implements "+className+" {");
+ p();
+ indent();
+
+ p(""+bufferClassName+" frozen;");
+ p(""+beanClassName+" bean;");
+ p();
+ p("public "+beanClassName+"() {");
+ indent();
+ p("this.bean = this;");
+ unindent();
+ p("}");
+ p();
+ p("public "+beanClassName+"("+beanClassName+" copy) {");
+ indent();
+ p("this.bean = copy;");
+ unindent();
+ p("}");
+ p();
+ p("public "+beanClassName+" copy() {");
+ indent();
+ p("return new "+beanClassName+"(bean);");
+ unindent();
+ p("}");
+ p();
+
+ generateMethodFreeze(m, bufferClassName);
+
+ p("private void copyCheck() {");
+ indent();
+ p("assert frozen==null : org.apache.activemq.protobuf.MessageBufferSupport.FORZEN_ERROR_MESSAGE;");
+ p("if (bean != this) {");
+ indent();
+ p("copy(bean);");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ p();
+
+ generateMethodCopyFromBean(m, beanClassName);
+
+ // Generate the field accessors..
+ for (FieldDescriptor field : m.getFields().values()) {
+ generateFieldAccessor(beanClassName, field);
+ }
+
+ generateMethodToString(m);
+
+ generateMethodMergeFromStream(m, beanClassName);
+
+ generateBeanEquals(m, beanClassName);
+
+ generateMethodMergeFromBean(m, className);
+
+ generateMethodClear(m);
+
+ unindent();
+ p("}");
+ p();
+
+ p("static public final class "+bufferClassName+" implements org.apache.activemq.protobuf.MessageBuffer, "+className+" {");
+ p();
+ indent();
+
+ p("private "+beanClassName+" bean;");
+ p("private org.apache.activemq.protobuf.Buffer buffer;");
+ p("private int size=-1;");
+ p("private int hashCode;");
+ p();
+ p("private "+bufferClassName+"(org.apache.activemq.protobuf.Buffer buffer) {");
+ indent();
+ p("this.buffer = buffer;");
+ unindent();
+ p("}");
+ p();
+ p("private "+bufferClassName+"("+beanClassName+" bean) {");
+ indent();
+ p("this.bean = bean;");
+ unindent();
+ p("}");
+ p();
+ p("public "+beanClassName+" copy() {");
+ indent();
+ p("return bean().copy();");
+ unindent();
+ p("}");
+ p();
+ p("public "+bufferClassName+" freeze() {");
+ indent();
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+ p("private "+beanClassName+" bean() {");
+ indent();
+ p("if (bean == null) {");
+ indent();
+ p("try {");
+ indent();
+ p("bean = new "+beanClassName+"().mergeUnframed(new org.apache.activemq.protobuf.CodedInputStream(buffer));");
+ p("bean.frozen=this;");
+ unindent();
+ p("} catch (org.apache.activemq.protobuf.InvalidProtocolBufferException e) {");
+ indent();
+ p("throw new RuntimeException(e);");
+ unindent();
+ p("} catch (java.io.IOException e) {");
+ indent();
+ p("throw new RuntimeException(\"An IOException was thrown (should never happen in this method).\", e);");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ p("return bean;");
+ unindent();
+ p("}");
+ p();
+
+ p("public String toString() {");
+ indent();
+ p("return bean().toString();");
+ unindent();
+ p("}");
+ p();
+ p("public java.lang.StringBuilder toString(java.lang.StringBuilder sb, String prefix) {");
+ indent();
+ p("return bean().toString(sb, prefix);");
+ unindent();
+ p("}");
+ p();
+
+ for (FieldDescriptor field : m.getFields().values()) {
+ generateBufferGetters(field);
+ }
+
+ generateMethodWrite(m);
+
+ generateMethodSerializedSize(m);
+
+ generateMethodParseFrom(m, bufferClassName, beanClassName);
+
+ generateBufferEquals(m, bufferClassName);
+
+ unindent();
+ p("}");
+ p();
+
+
+// generateMethodVisitor(m);
+// generateMethodType(m, className);
+
+
+ unindent();
+ p("}");
+ p();
+
+ }
+
+ private void generateMethodFreeze(MessageDescriptor m, String bufferClassName) {
+ p("public boolean frozen() {");
+ indent();
+ p("return frozen!=null;");
+ unindent();
+ p("}");
+ p();
+ p("public "+bufferClassName+" freeze() {");
+ indent();
+ p("if( frozen==null ) {");
+ indent();
+ p("frozen = new "+bufferClassName+"(bean);");
+ p("frozen.serializedSizeUnframed();");
+ unindent();
+ p("}");
+ p("return frozen;");
+ unindent();
+ p("}");
+ p();
+ }
+
+ /**
+ * @param m
+ * @param className
+ */
+ private void generateMethodCopyFromBean(MessageDescriptor m, String className) {
+ p("private void copy("+className+" other) {");
+ indent();
+ p("this.bean = this;");
+ for (FieldDescriptor field : m.getFields().values()) {
+ String lname = lCamel(field.getName());
+ String type = field.getRule()==FieldDescriptor.REPEATED_RULE ? javaCollectionType(field):javaType(field);
+ boolean primitive = field.getTypeDescriptor()==null || field.getTypeDescriptor().isEnum();
+ if( field.isRepeated() ) {
+ if( primitive ) {
+ p("this.f_" + lname + " = other.f_" + lname + ";");
+ p("if( this.f_" + lname + " !=null && !other.frozen()) {");
+ indent();
+ p("this.f_" + lname + " = new java.util.ArrayList<"+type+">(this.f_" + lname + ");");
+ unindent();
+ p("}");
+ } else {
+ p("this.f_" + lname + " = other.f_" + lname + ";");
+ p("if( this.f_" + lname + " !=null) {");
+ indent();
+ p("this.f_" + lname + " = new java.util.ArrayList<"+type+">(other.f_" + lname + ".size());");
+ p("for( "+type+" e : other.f_" + lname + ") {");
+ indent();
+ p("this.f_" + lname + ".add(e.copy());");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ }
+ } else {
+ if( primitive ) {
+ p("this.f_" + lname + " = other.f_" + lname + ";");
+ p("this.b_" + lname + " = other.b_" + lname + ";");
+ } else {
+ p("this.f_" + lname + " = other.f_" + lname + ";");
+ p("if( this.f_" + lname + " !=null ) {");
+ indent();
+ p("this.f_" + lname + " = this.f_" + lname + ".copy();");
+ unindent();
+ p("}");
+ }
+ }
+ }
+ unindent();
+ p("}");
+ p();
+ }
+
+
+ /**
+ * If the java_visitor message option is set, then this method generates a visitor method. The option
+ * speifiies the class name of the visitor and optionally the return value and exceptions thrown by the visitor.
+ *
+ * Examples:
+ *
+ * option java_visitor = "org.apache.kahadb.store.Visitor";
+ * generates:
+ * public void visit(org.apache.kahadb.store.Visitor visitor) {
+ * visitor.visit(this);
+ * }
+ *
+ * option java_visitor = "org.apache.kahadb.store.Visitor:int:java.io.IOException";
+ * generates:
+ * public int visit(org.apache.kahadb.store.Visitor visitor) throws java.io.IOException {
+ * return visitor.visit(this);
+ * }
+ *
+ * @param m
+ */
+ private void generateMethodVisitor(MessageDescriptor m) {
+ String javaVisitor = getOption(m.getOptions(), "java_visitor", null);
+ if( javaVisitor!=null ) {
+ String returns = "void";
+ String throwsException = null;
+
+ StringTokenizer st = new StringTokenizer(javaVisitor, ":");
+ String vistorClass = st.nextToken();
+ if( st.hasMoreTokens() ) {
+ returns = st.nextToken();
+ }
+ if( st.hasMoreTokens() ) {
+ throwsException = st.nextToken();
+ }
+
+ String throwsClause = "";
+ if( throwsException!=null ) {
+ throwsClause = "throws "+throwsException+" ";
+ }
+
+ p("public "+returns+" visit("+vistorClass+" visitor) "+throwsClause+ "{");
+ indent();
+ if( "void".equals(returns) ) {
+ p("visitor.visit(this);");
+ } else {
+ p("return visitor.visit(this);");
+ }
+ unindent();
+ p("}");
+ p();
+ }
+ }
+
+ private void generateMethodType(MessageDescriptor m, String className) {
+ String typeEnum = getOption(m.getOptions(), "java_type_method", null);
+ if( typeEnum!=null ) {
+
+ TypeDescriptor typeDescriptor = m.getType(typeEnum);
+ if( typeDescriptor == null ) {
+ typeDescriptor = m.getProtoDescriptor().getType(typeEnum);
+ }
+ if( typeDescriptor == null || !typeDescriptor.isEnum() ) {
+ errors.add("The java_type_method option on the "+m.getName()+" message does not point to valid enum type");
+ return;
+ }
+
+
+ String constant = constantCase(className);
+ EnumDescriptor enumDescriptor = (EnumDescriptor)typeDescriptor;
+ if( enumDescriptor.getFields().get(constant) == null ) {
+ errors.add("The java_type_method option on the "+m.getName()+" message does not points to the "+typeEnum+" enum but it does not have an entry for "+constant);
+ }
+
+ String type = javaType(typeDescriptor);
+
+ p("public "+type+" type() {");
+ indent();
+ p("return "+type+"."+constant+";");
+ unindent();
+ p("}");
+ p();
+ }
+ }
+
+ private void generateMethodParseFrom(MessageDescriptor m, String bufferClassName, String beanClassName) {
+ p("public static "+beanClassName+" parseUnframed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ indent();
+ p("return new "+beanClassName+"().mergeUnframed(data);");
+ unindent();
+ p("}");
+ p();
+ p("public static "+beanClassName+" parseUnframed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ indent();
+ p("return parseUnframed(new org.apache.activemq.protobuf.CodedInputStream(data));");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseUnframed(org.apache.activemq.protobuf.Buffer data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
+ indent();
+ p("return new "+bufferClassName+"(data);");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseUnframed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
+ indent();
+ p("return parseUnframed(new org.apache.activemq.protobuf.Buffer(data));");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseFramed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ indent();
+ p("int length = data.readRawVarint32();");
+ p("int oldLimit = data.pushLimit(length);");
+ p(""+bufferClassName+" rc = parseUnframed(data.readRawBytes(length));");
+ p("data.popLimit(oldLimit);");
+ p("return rc;");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseFramed(org.apache.activemq.protobuf.Buffer data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
+ indent();
+ p("try {");
+ indent();
+ p("org.apache.activemq.protobuf.CodedInputStream input = new org.apache.activemq.protobuf.CodedInputStream(data);");
+ p(""+bufferClassName+" rc = parseFramed(input);");
+ p("input.checkLastTagWas(0);");
+ p("return rc;");
+ unindent();
+ p("} catch (org.apache.activemq.protobuf.InvalidProtocolBufferException e) {");
+ indent();
+ p("throw e;");
+ unindent();
+ p("} catch (java.io.IOException e) {");
+ indent();
+ p("throw new RuntimeException(\"An IOException was thrown (should never happen in this method).\", e);");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseFramed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
+ indent();
+ p("return parseFramed(new org.apache.activemq.protobuf.Buffer(data));");
+ unindent();
+ p("}");
+ p();
+ p("public static "+bufferClassName+" parseFramed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ indent();
+ p("return parseUnframed(org.apache.activemq.protobuf.MessageBufferSupport.readFrame(data));");
+ unindent();
+ p("}");
+ p();
+
+ }
+
+ private void generateBeanEquals(MessageDescriptor m, String className) {
+ p("public boolean equals(Object obj) {");
+ indent();
+ p("if( obj==this )");
+ p(" return true;");
+ p("");
+ p("if( obj==null || obj.getClass()!="+className+".class )");
+ p(" return false;");
+ p("");
+ p("return equals(("+className+")obj);");
+ unindent();
+ p("}");
+ p("");
+
+ p("public boolean equals("+className+" obj) {");
+ indent();
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ String getterMethod="get"+uname+"()";
+ String hasMethod = "has"+uname+"()";
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ getterMethod = "get"+uname+"List()";
+ }
+
+ p("if ("+hasMethod+" ^ obj."+hasMethod+" ) ");
+ p(" return false;");
+
+
+
+ if( field.getRule() != FieldDescriptor.REPEATED_RULE && (field.isNumberType() || field.getType()==FieldDescriptor.BOOL_TYPE) ) {
+ p("if ("+hasMethod+" && ( "+getterMethod+"!=obj."+getterMethod+" ))");
+ } else {
+ p("if ("+hasMethod+" && ( !"+getterMethod+".equals(obj."+getterMethod+") ))");
+ }
+ p(" return false;");
+ }
+ p("return true;");
+ unindent();
+ p("}");
+ p("");
+ p("public int hashCode() {");
+ indent();
+ int hc = className.hashCode();
+ p("int rc="+hc+";");
+ int counter=0;
+ for (FieldDescriptor field : m.getFields().values()) {
+ counter++;
+
+ String uname = uCamel(field.getName());
+ String getterMethod="get"+uname+"()";
+ String hasMethod = "has"+uname+"()";
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ getterMethod = "get"+uname+"List()";
+ }
+
+ p("if ("+hasMethod+") {");
+ indent();
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ p("rc ^= ( "+uname.hashCode()+"^"+getterMethod+".hashCode() );");
+ } else if( field.isInteger32Type() ) {
+ p("rc ^= ( "+uname.hashCode()+"^"+getterMethod+" );");
+ } else if( field.isInteger64Type() ) {
+ p("rc ^= ( "+uname.hashCode()+"^(new Long("+getterMethod+")).hashCode() );");
+ } else if( field.getType()==FieldDescriptor.DOUBLE_TYPE ) {
+ p("rc ^= ( "+uname.hashCode()+"^(new Double("+getterMethod+")).hashCode() );");
+ } else if( field.getType()==FieldDescriptor.FLOAT_TYPE ) {
+ p("rc ^= ( "+uname.hashCode()+"^(new Double("+getterMethod+")).hashCode() );");
+ } else if( field.getType()==FieldDescriptor.BOOL_TYPE ) {
+ p("rc ^= ( "+uname.hashCode()+"^ ("+getterMethod+"? "+counter+":-"+counter+") );");
+ } else {
+ p("rc ^= ( "+uname.hashCode()+"^"+getterMethod+".hashCode() );");
+ }
+ unindent();
+ p("}");
+ }
+ p("return rc;");
+ unindent();
+ p("}");
+ p("");
+ }
+
+ private void generateBufferEquals(MessageDescriptor m, String className) {
+ p("public boolean equals(Object obj) {");
+ indent();
+ p("if( obj==this )");
+ p(" return true;");
+ p("");
+ p("if( obj==null || obj.getClass()!="+className+".class )");
+ p(" return false;");
+ p("");
+ p("return equals(("+className+")obj);");
+ unindent();
+ p("}");
+ p("");
+
+ p("public boolean equals("+className+" obj) {");
+ indent();
+ p("return toUnframedBuffer().equals(obj.toUnframedBuffer());");
+ unindent();
+ p("}");
+ p("");
+ p("public int hashCode() {");
+ indent();
+ int hc = className.hashCode();
+ p("if( hashCode==0 ) {");
+ p("hashCode="+hc+" ^ toUnframedBuffer().hashCode();");
+ p("}");
+ p("return hashCode;");
+ unindent();
+ p("}");
+ p("");
+ }
+
+ /**
+ * @param m
+ */
+ private void generateMethodSerializedSize(MessageDescriptor m) {
+
+ p("public int serializedSizeFramed() {");
+ indent();
+ p("int t = serializedSizeUnframed();");
+ p("return org.apache.activemq.protobuf.CodedOutputStream.computeRawVarint32Size(t) + t;");
+ unindent();
+ p("}");
+ p();
+ p("public int serializedSizeUnframed() {");
+ indent();
+ p("if (buffer != null) {");
+ indent();
+ p("return buffer.length;");
+ unindent();
+ p("}");
+ p("if (size != -1)");
+ p(" return size;");
+ p();
+ p("size = 0;");
+ for (FieldDescriptor field : m.getFields().values()) {
+
+ String uname = uCamel(field.getName());
+ String getter="get"+uname+"()";
+ String type = javaType(field);
+
+ if( !field.isRequired() ) {
+ p("if (has"+uname+"()) {");
+ indent();
+ }
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ p("for ("+type+" i : get"+uname+"List()) {");
+ indent();
+ getter = "i";
+ }
+
+ if( field.getType()==FieldDescriptor.STRING_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeStringSize("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.BYTES_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBytesSize("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.BOOL_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBoolSize("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.DOUBLE_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeDoubleSize("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FLOAT_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFloatSize("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.INT32_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt32Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.INT64_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt64Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SINT32_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt32Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SINT64_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt64Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.UINT32_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt32Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.UINT64_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt64Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FIXED32_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed32Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FIXED64_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed64Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SFIXED32_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed32Size("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SFIXED64_TYPE ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed64Size("+field.getTag()+", "+getter+");");
+ } else if( field.getTypeDescriptor().isEnum() ) {
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeEnumSize("+field.getTag()+", "+getter+".getNumber());");
+ } else if ( field.getGroup()!=null ) {
+ errors.add("This code generator does not support group fields.");
+// p("size += org.apache.activemq.protobuf.MessageBufferSupport.computeGroupSize("+field.getTag()+", ("+type+"Buffer)"+getter+");");
+ } else {
+ p("size += org.apache.activemq.protobuf.MessageBufferSupport.computeMessageSize("+field.getTag()+", "+getter+".freeze());");
+ }
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ unindent();
+ p("}");
+ }
+
+ if( !field.isRequired() ) {
+ unindent();
+ p("}");
+ }
+
+ }
+ // TODO: handle unknown fields
+ // size += getUnknownFields().getSerializedSize();");
+ p("return size;");
+ unindent();
+ p("}");
+ p();
+ }
+
+ /**
+ * @param m
+ */
+ private void generateMethodWrite(MessageDescriptor m) {
+
+ p("public org.apache.activemq.protobuf.Buffer toUnframedBuffer() {");
+ indent();
+ p("if( buffer !=null ) {");
+ indent();
+ p("return buffer;");
+ unindent();
+ p("}");
+ p("return org.apache.activemq.protobuf.MessageBufferSupport.toUnframedBuffer(this);");
+ unindent();
+ p("}");
+ p();
+ p("public org.apache.activemq.protobuf.Buffer toFramedBuffer() {");
+ indent();
+ p("return org.apache.activemq.protobuf.MessageBufferSupport.toFramedBuffer(this);");
+ unindent();
+ p("}");
+ p();
+ p("public byte[] toUnframedByteArray() {");
+ indent();
+ p("return toUnframedBuffer().toByteArray();");
+ unindent();
+ p("}");
+ p();
+ p("public byte[] toFramedByteArray() {");
+ indent();
+ p("return toFramedBuffer().toByteArray();");
+ unindent();
+ p("}");
+ p();
+ p("public void writeFramed(org.apache.activemq.protobuf.CodedOutputStream output) throws java.io.IOException {");
+ indent();
+ p("output.writeRawVarint32(serializedSizeUnframed());");
+ p("writeUnframed(output);");
+ unindent();
+ p("}");
+ p();
+ p("public void writeFramed(java.io.OutputStream output) throws java.io.IOException {");
+ indent();
+ p("org.apache.activemq.protobuf.CodedOutputStream codedOutput = new org.apache.activemq.protobuf.CodedOutputStream(output);");
+ p("writeFramed(codedOutput);");
+ p("codedOutput.flush();");
+ unindent();
+ p("}");
+ p();
+
+ p("public void writeUnframed(java.io.OutputStream output) throws java.io.IOException {");
+ indent();
+ p("org.apache.activemq.protobuf.CodedOutputStream codedOutput = new org.apache.activemq.protobuf.CodedOutputStream(output);");
+ p("writeUnframed(codedOutput);");
+ p("codedOutput.flush();");
+ unindent();
+ p("}");
+ p();
+
+ p("public void writeUnframed(org.apache.activemq.protobuf.CodedOutputStream output) throws java.io.IOException {");
+ indent();
+
+ p("if (buffer == null) {");
+ indent();
+ p("int size = serializedSizeUnframed();");
+ p("buffer = output.getNextBuffer(size);");
+ p("org.apache.activemq.protobuf.CodedOutputStream original=null;");
+ p("if( buffer == null ) {");
+ indent();
+ p("buffer = new org.apache.activemq.protobuf.Buffer(new byte[size]);");
+ p("original = output;");
+ p("output = new org.apache.activemq.protobuf.CodedOutputStream(buffer);");
+ unindent();
+ p("}");
+
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ String getter="bean.get"+uname+"()";
+ String type = javaType(field);
+
+ if( !field.isRequired() ) {
+ p("if (bean.has"+uname+"()) {");
+ indent();
+ }
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ p("for ("+type+" i : bean.get"+uname+"List()) {");
+ indent();
+ getter = "i";
+ }
+
+ if( field.getType()==FieldDescriptor.STRING_TYPE ) {
+ p("output.writeString("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.BYTES_TYPE ) {
+ p("output.writeBytes("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.BOOL_TYPE ) {
+ p("output.writeBool("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.DOUBLE_TYPE ) {
+ p("output.writeDouble("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FLOAT_TYPE ) {
+ p("output.writeFloat("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.INT32_TYPE ) {
+ p("output.writeInt32("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.INT64_TYPE ) {
+ p("output.writeInt64("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SINT32_TYPE ) {
+ p("output.writeSInt32("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SINT64_TYPE ) {
+ p("output.writeSInt64("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.UINT32_TYPE ) {
+ p("output.writeUInt32("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.UINT64_TYPE ) {
+ p("output.writeUInt64("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FIXED32_TYPE ) {
+ p("output.writeFixed32("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.FIXED64_TYPE ) {
+ p("output.writeFixed64("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SFIXED32_TYPE ) {
+ p("output.writeSFixed32("+field.getTag()+", "+getter+");");
+ } else if( field.getType()==FieldDescriptor.SFIXED64_TYPE ) {
+ p("output.writeSFixed64("+field.getTag()+", "+getter+");");
+ } else if( field.getTypeDescriptor().isEnum() ) {
+ p("output.writeEnum("+field.getTag()+", "+getter+".getNumber());");
+ } else if ( field.getGroup()!=null ) {
+ errors.add("This code generator does not support group fields.");
+// p("writeGroup(output, "+field.getTag()+", "+getter+");");
+ } else {
+ p("org.apache.activemq.protobuf.MessageBufferSupport.writeMessage(output, "+field.getTag()+", "+getter+".freeze());");
+ }
+
+ if( field.getRule() == FieldDescriptor.REPEATED_RULE ) {
+ unindent();
+ p("}");
+ }
+
+ if( !field.isRequired() ) {
+ unindent();
+ p("}");
+ }
+ }
+
+ p("if( original !=null ) {");
+ indent();
+ p("output.checkNoSpaceLeft();");
+ p("output = original;");
+ p("output.writeRawBytes(buffer);");
+ unindent();
+ p("}");
+ unindent();
+ p("} else {");
+ indent();
+ p("output.writeRawBytes(buffer);");
+ unindent();
+ p("}");
+
+ unindent();
+ p("}");
+ p();
+ }
+
+ /**
+ * @param m
+ * @param className
+ */
+ private void generateMethodMergeFromStream(MessageDescriptor m, String className) {
+ p("public "+className+" mergeUnframed(java.io.InputStream input) throws java.io.IOException {");
+ indent();
+ p("return mergeUnframed(new org.apache.activemq.protobuf.CodedInputStream(input));");
+ unindent();
+ p("}");
+ p();
+ p("public "+className+" mergeUnframed(org.apache.activemq.protobuf.CodedInputStream input) throws java.io.IOException {");
+ indent();
+ {
+ p("copyCheck();");
+ p("while (true) {");
+ indent();
+ {
+ p("int tag = input.readTag();");
+ p("if ((tag & 0x07) == 4) {");
+ p(" return this;");
+ p("}");
+
+ p("switch (tag) {");
+ p("case 0:");
+ p(" return this;");
+ p("default: {");
+
+ p(" break;");
+ p("}");
+
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ String setter = "set" + uname;
+ boolean repeated = field.getRule() == FieldDescriptor.REPEATED_RULE;
+ if (repeated) {
+ setter = "create" + uname + "List().add";
+ }
+ if (field.getType() == FieldDescriptor.STRING_TYPE) {
+ p("case "
+ + makeTag(field.getTag(),
+ WIRETYPE_LENGTH_DELIMITED) + ":");
+ indent();
+ p(setter + "(input.readString());");
+ } else if (field.getType() == FieldDescriptor.BYTES_TYPE) {
+ p("case "
+ + makeTag(field.getTag(),
+ WIRETYPE_LENGTH_DELIMITED) + ":");
+ indent();
+ p(setter + "(input.readBytes());");
+ } else if (field.getType() == FieldDescriptor.BOOL_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readBool());");
+ } else if (field.getType() == FieldDescriptor.DOUBLE_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED64)
+ + ":");
+ indent();
+ p(setter + "(input.readDouble());");
+ } else if (field.getType() == FieldDescriptor.FLOAT_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED32)
+ + ":");
+ indent();
+ p(setter + "(input.readFloat());");
+ } else if (field.getType() == FieldDescriptor.INT32_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readInt32());");
+ } else if (field.getType() == FieldDescriptor.INT64_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readInt64());");
+ } else if (field.getType() == FieldDescriptor.SINT32_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readSInt32());");
+ } else if (field.getType() == FieldDescriptor.SINT64_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readSInt64());");
+ } else if (field.getType() == FieldDescriptor.UINT32_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readUInt32());");
+ } else if (field.getType() == FieldDescriptor.UINT64_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ p(setter + "(input.readUInt64());");
+ } else if (field.getType() == FieldDescriptor.FIXED32_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED32)
+ + ":");
+ indent();
+ p(setter + "(input.readFixed32());");
+ } else if (field.getType() == FieldDescriptor.FIXED64_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED64)
+ + ":");
+ indent();
+ p(setter + "(input.readFixed64());");
+ } else if (field.getType() == FieldDescriptor.SFIXED32_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED32)
+ + ":");
+ indent();
+ p(setter + "(input.readSFixed32());");
+ } else if (field.getType() == FieldDescriptor.SFIXED64_TYPE) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_FIXED64)
+ + ":");
+ indent();
+ p(setter + "(input.readSFixed64());");
+ } else if (field.getTypeDescriptor().isEnum()) {
+ p("case " + makeTag(field.getTag(), WIRETYPE_VARINT)
+ + ":");
+ indent();
+ String type = javaType(field);
+ p("{");
+ indent();
+ p("int t = input.readEnum();");
+ p("" + type + " value = " + type + ".valueOf(t);");
+ p("if( value !=null ) {");
+ indent();
+ p(setter + "(value);");
+ unindent();
+ p("}");
+ // TODO: else store it as an known
+
+ unindent();
+ p("}");
+
+ } else if (field.getGroup() != null) {
+ errors.add("This code generator does not support group fields.");
+// p("case "+ makeTag(field.getTag(), WIRETYPE_START_GROUP)+ ":");
+// indent();
+// String type = javaType(field);
+// if (repeated) {
+// p(setter + "(readGroup(input, " + field.getTag()+ ", new " + type + "()));");
+// } else {
+// p("if (has" + uname + "()) {");
+// indent();
+// p("readGroup(input, " + field.getTag() + ", get"
+// + uname + "());");
+// unindent();
+// p("} else {");
+// indent();
+// p(setter + "(readGroup(input, " + field.getTag()
+// + ",new " + type + "()));");
+// unindent();
+// p("}");
+// }
+// p("");
+ } else {
+ p("case "+ makeTag(field.getTag(),WIRETYPE_LENGTH_DELIMITED) + ":");
+ indent();
+ String type = javaType(field);
+ if (repeated) {
+ p(setter + "("+type+"."+type+"Buffer.parseFramed(input));");
+ } else {
+ p("if (has" + uname + "()) {");
+ indent();
+ p("set" + uname + "(get" + uname + "().copy().mergeFrom("+type+"."+type+"Buffer.parseFramed(input)));");
+ unindent();
+ p("} else {");
+ indent();
+ p(setter + "("+type+"."+type+"Buffer.parseFramed(input));");
+ unindent();
+ p("}");
+ }
+ }
+ p("break;");
+ unindent();
+ }
+ p("}");
+ }
+ unindent();
+ p("}");
+ }
+ unindent();
+ p("}");
+ }
+
+ /**
+ * @param m
+ * @param className
+ */
+ private void generateMethodMergeFromBean(MessageDescriptor m, String className) {
+ p("public "+className+"Bean mergeFrom("+className+" other) {");
+ indent();
+ p("copyCheck();");
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ p("if (other.has"+uname+"()) {");
+ indent();
+
+ if( field.isScalarType() || field.getTypeDescriptor().isEnum() ) {
+ if( field.isRepeated() ) {
+ p("get"+uname+"List().addAll(other.get"+uname+"List());");
+ } else {
+ p("set"+uname+"(other.get"+uname+"());");
+ }
+ } else {
+
+ String type = javaType(field);
+ // It's complex type...
+ if( field.isRepeated() ) {
+ p("for("+type+" element: other.get"+uname+"List() ) {");
+ indent();
+ p("get"+uname+"List().add(element.copy());");
+ unindent();
+ p("}");
+ } else {
+ p("if (has"+uname+"()) {");
+ indent();
+ p("set"+uname+"(get"+uname+"().copy().mergeFrom(other.get"+uname+"()));");
+ unindent();
+ p("} else {");
+ indent();
+ p("set"+uname+"(other.get"+uname+"().copy());");
+ unindent();
+ p("}");
+ }
+ }
+ unindent();
+ p("}");
+ }
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+ }
+
+ /**
+ * @param m
+ */
+ private void generateMethodClear(MessageDescriptor m) {
+ p("public void clear() {");
+ indent();
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ p("clear" + uname + "();");
+ }
+ unindent();
+ p("}");
+ p();
+ }
+
+// private void generateMethodAssertInitialized(MessageDescriptor m, String className) {
+//
+// p("public java.util.ArrayList<String> missingFields() {");
+// indent();
+// p("java.util.ArrayList<String> missingFields = super.missingFields();");
+//
+// for (FieldDescriptor field : m.getFields().values()) {
+// String uname = uCamel(field.getName());
+// if( field.isRequired() ) {
+// p("if( !has" + uname + "() ) {");
+// indent();
+// p("missingFields.add(\""+field.getName()+"\");");
+// unindent();
+// p("}");
+// }
+// }
+//
+// if( !deferredDecode ) {
+// for (FieldDescriptor field : m.getFields().values()) {
+// if( field.getTypeDescriptor()!=null && !field.getTypeDescriptor().isEnum()) {
+// String uname = uCamel(field.getName());
+// p("if( has" + uname + "() ) {");
+// indent();
+// if( !field.isRepeated() ) {
+// p("try {");
+// indent();
+// p("get" + uname + "().assertInitialized();");
+// unindent();
+// p("} catch (org.apache.activemq.protobuf.UninitializedMessageException e){");
+// indent();
+// p("missingFields.addAll(prefix(e.getMissingFields(),\""+field.getName()+".\"));");
+// unindent();
+// p("}");
+// } else {
+// String type = javaCollectionType(field);
+// p("java.util.List<"+type+"> l = get" + uname + "List();");
+// p("for( int i=0; i < l.size(); i++ ) {");
+// indent();
+// p("try {");
+// indent();
+// p("l.get(i).assertInitialized();");
+// unindent();
+// p("} catch (org.apache.activemq.protobuf.UninitializedMessageException e){");
+// indent();
+// p("missingFields.addAll(prefix(e.getMissingFields(),\""+field.getName()+"[\"+i+\"]\"));");
+// unindent();
+// p("}");
+// unindent();
+// p("}");
+// }
+// unindent();
+// p("}");
+// }
+// }
+// }
+// p("return missingFields;");
+// unindent();
+// p("}");
+// p();
+// }
+
+ private void generateMethodToString(MessageDescriptor m) {
+
+ p("public String toString() {");
+ indent();
+ p("return toString(new java.lang.StringBuilder(), \"\").toString();");
+ unindent();
+ p("}");
+ p();
+
+ p("public java.lang.StringBuilder toString(java.lang.StringBuilder sb, String prefix) {");
+ indent();
+ for (FieldDescriptor field : m.getFields().values()) {
+ String uname = uCamel(field.getName());
+ p("if( has" + uname + "() ) {");
+ indent();
+ if( field.isRepeated() ) {
+ String type = javaCollectionType(field);
+ p("java.util.List<"+type+"> l = get" + uname + "List();");
+ p("for( int i=0; i < l.size(); i++ ) {");
+ indent();
+ if( field.getTypeDescriptor()!=null && !field.getTypeDescriptor().isEnum()) {
+ p("sb.append(prefix+\""+field.getName()+"[\"+i+\"] {\\n\");");
+ p("l.get(i).toString(sb, prefix+\" \");");
+ p("sb.append(prefix+\"}\\n\");");
+ } else {
+ p("sb.append(prefix+\""+field.getName()+"[\"+i+\"]: \");");
+ p("sb.append(l.get(i));");
+ p("sb.append(\"\\n\");");
+ }
+ unindent();
+ p("}");
+ } else {
+ if( field.getTypeDescriptor()!=null && !field.getTypeDescriptor().isEnum()) {
+ p("sb.append(prefix+\""+field.getName()+" {\\n\");");
+ p("get" + uname + "().toString(sb, prefix+\" \");");
+ p("sb.append(prefix+\"}\\n\");");
+ } else {
+ p("sb.append(prefix+\""+field.getName()+": \");");
+ p("sb.append(get" + uname + "());");
+ p("sb.append(\"\\n\");");
+ }
+ }
+ unindent();
+ p("}");
+ }
+ p("return sb;");
+ unindent();
+ p("}");
+ p();
+
+ }
+
+ /**
+ * @param field
+ * @param className
+ */
+ private void generateBufferGetters(FieldDescriptor field) {
+ String uname = uCamel(field.getName());
+ String type = field.getRule()==FieldDescriptor.REPEATED_RULE ? javaCollectionType(field):javaType(field);
+ boolean repeated = field.getRule()==FieldDescriptor.REPEATED_RULE;
+
+ // Create the fields..
+ p("// " + field.getRule() + " " + field.getType() + " " + field.getName() + " = " + field.getTag() + ";");
+ if( repeated ) {
+ // Create the field accessors
+ p("public boolean has" + uname + "() {");
+ indent();
+ p("return bean().has" + uname + "();");
+ unindent();
+ p("}");
+ p();
+ p("public java.util.List<" + type + "> get" + uname + "List() {");
+ indent();
+ p("return bean().get" + uname + "List();");
+ unindent();
+ p("}");
+ p();
+ p("public int get" + uname + "Count() {");
+ indent();
+ p("return bean().get" + uname + "Count();");
+ unindent();
+ p("}");
+ p();
+ p("public " + type + " get" + uname + "(int index) {");
+ indent();
+ p("return bean().get" + uname + "(index);");
+ unindent();
+ p("}");
+ p();
+ } else {
+ // Create the field accessors
+ p("public boolean has" + uname + "() {");
+ indent();
+ p("return bean().has" + uname + "();");
+ unindent();
+ p("}");
+ p();
+ p("public " + type + " get" + uname + "() {");
+ indent();
+ p("return bean().get" + uname + "();");
+ unindent();
+ p("}");
+ p();
+ }
+ }
+
+ /**
+ * @param field
+ * @param className
+ */
+ private void generateFieldGetterSignatures(FieldDescriptor field) {
+ String uname = uCamel(field.getName());
+ String type = field.getRule()==FieldDescriptor.REPEATED_RULE ? javaCollectionType(field):javaType(field);
+ boolean repeated = field.getRule()==FieldDescriptor.REPEATED_RULE;
+
+ // Create the fields..
+ p("// " + field.getRule() + " " + field.getType() + " " + field.getName() + " = " + field.getTag() + ";");
+ if( repeated ) {
+ // Create the field accessors
+ p("public boolean has" + uname + "();");
+ p("public java.util.List<" + type + "> get" + uname + "List();");
+ p("public int get" + uname + "Count();");
+ p("public " + type + " get" + uname + "(int index);");
+ } else {
+ // Create the field accessors
+ p("public boolean has" + uname + "();");
+ p("public " + type + " get" + uname + "();");
+ }
+ }
+
+
+ /**
+ * @param field
+ * @param className
+ */
+ private void generateFieldAccessor(String beanClassName, FieldDescriptor field) {
+
+ String lname = lCamel(field.getName());
+ String uname = uCamel(field.getName());
+ String type = field.getRule()==FieldDescriptor.REPEATED_RULE ? javaCollectionType(field):javaType(field);
+ String typeDefault = javaTypeDefault(field);
+ boolean primitive = field.getTypeDescriptor()==null || field.getTypeDescriptor().isEnum();
+ boolean repeated = field.getRule()==FieldDescriptor.REPEATED_RULE;
+
+ // Create the fields..
+ p("// " + field.getRule() + " " + field.getType() + " " + field.getName() + " = " + field.getTag() + ";");
+
+ if( repeated ) {
+ p("private java.util.List<" + type + "> f_" + lname + ";");
+ p();
+
+ // Create the field accessors
+ p("public boolean has" + uname + "() {");
+ indent();
+ p("return bean.f_" + lname + "!=null && !bean.f_" + lname + ".isEmpty();");
+ unindent();
+ p("}");
+ p();
+
+ p("public java.util.List<" + type + "> get" + uname + "List() {");
+ indent();
+ p("return bean.f_" + lname + ";");
+ unindent();
+ p("}");
+ p();
+
+ p("public java.util.List<" + type + "> create" + uname + "List() {");
+ indent();
+ p("copyCheck();");
+ p("if( this.f_" + lname + " == null ) {");
+ indent();
+ p("this.f_" + lname + " = new java.util.ArrayList<" + type + ">();");
+ unindent();
+ p("}");
+ p("return bean.f_" + lname + ";");
+ unindent();
+ p("}");
+ p();
+
+ p("public "+beanClassName+" set" + uname + "List(java.util.List<" + type + "> " + lname + ") {");
+ indent();
+ p("copyCheck();");
+ p("this.f_" + lname + " = " + lname + ";");
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+
+ p("public int get" + uname + "Count() {");
+ indent();
+ p("if( bean.f_" + lname + " == null ) {");
+ indent();
+ p("return 0;");
+ unindent();
+ p("}");
+ p("return bean.f_" + lname + ".size();");
+ unindent();
+ p("}");
+ p();
+
+ p("public " + type + " get" + uname + "(int index) {");
+ indent();
+ p("if( bean.f_" + lname + " == null ) {");
+ indent();
+ p("return null;");
+ unindent();
+ p("}");
+ p("return bean.f_" + lname + ".get(index);");
+ unindent();
+ p("}");
+ p();
+
+ p("public "+beanClassName+" set" + uname + "(int index, " + type + " value) {");
+ indent();
+ p("this.create" + uname + "List().set(index, value);");
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+
+ p("public "+beanClassName+" add" + uname + "(" + type + " value) {");
+ indent();
+ p("this.create" + uname + "List().add(value);");
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+
+ p("public "+beanClassName+" addAll" + uname + "(java.lang.Iterable<? extends " + type + "> collection) {");
+ indent();
+ p("org.apache.activemq.protobuf.MessageBufferSupport.addAll(collection, this.create" + uname + "List());");
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+
+ p("public void clear" + uname + "() {");
+ indent();
+ p("copyCheck();");
+ p("this.f_" + lname + " = null;");
+ unindent();
+ p("}");
+ p();
+
+ } else {
+
+ p("private " + type + " f_" + lname + " = "+typeDefault+";");
+ if (primitive) {
+ p("private boolean b_" + lname + ";");
+ }
+ p();
+
+ // Create the field accessors
+ p("public boolean has" + uname + "() {");
+ indent();
+ if (primitive) {
+ p("return bean.b_" + lname + ";");
+ } else {
+ p("return bean.f_" + lname + "!=null;");
+ }
+ unindent();
+ p("}");
+ p();
+
+ p("public " + type + " get" + uname + "() {");
+ indent();
+ p("return bean.f_" + lname + ";");
+ unindent();
+ p("}");
+ p();
+
+ p("public "+beanClassName+" set" + uname + "(" + type + " " + lname + ") {");
+ indent();
+ p("copyCheck();");
+ if (primitive) {
+ if( auto_clear_optional_fields && field.isOptional() ) {
+ if( field.isStringType() && !"null".equals(typeDefault)) {
+ p("this.b_" + lname + " = ("+lname+" != "+typeDefault+");");
+ } else {
+ p("this.b_" + lname + " = ("+lname+" != "+typeDefault+");");
+ }
+ } else {
+ p("this.b_" + lname + " = true;");
+ }
+ }
+ p("this.f_" + lname + " = " + lname + ";");
+ p("return this;");
+ unindent();
+ p("}");
+ p();
+
+ p("public void clear" + uname + "() {");
+ indent();
+ p("copyCheck();");
+ if (primitive) {
+ p("this.b_" + lname + " = false;");
+ }
+ p("this.f_" + lname + " = " + typeDefault + ";");
+ unindent();
+ p("}");
+ p();
+ }
+
+ }
+
+ private String javaTypeDefault(FieldDescriptor field) {
+ OptionDescriptor defaultOption = field.getOptions().get("default");
+ if( defaultOption!=null ) {
+ if( field.isStringType() ) {
+ return asJavaString(defaultOption.getValue());
+ } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
+ return "new org.apache.activemq.protobuf.Buffer("+asJavaString(defaultOption.getValue())+")";
+ } else if( field.isInteger32Type() ) {
+ int v;
+ if( field.getType() == FieldDescriptor.UINT32_TYPE ) {
+ v = TextFormat.parseUInt32(defaultOption.getValue());
+ } else {
+ v = TextFormat.parseInt32(defaultOption.getValue());
+ }
+ return ""+v;
+ } else if( field.isInteger64Type() ) {
+ long v;
+ if( field.getType() == FieldDescriptor.UINT64_TYPE ) {
+ v = TextFormat.parseUInt64(defaultOption.getValue());
+ } else {
+ v = TextFormat.parseInt64(defaultOption.getValue());
+ }
+ return ""+v+"l";
+ } else if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) {
+ double v = Double.valueOf(defaultOption.getValue());
+ return ""+v+"d";
+ } else if( field.getType() == FieldDescriptor.FLOAT_TYPE ) {
+ float v = Float.valueOf(defaultOption.getValue());
+ return ""+v+"f";
+ } else if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
+ boolean v = Boolean.valueOf(defaultOption.getValue());
+ return ""+v;
+ } else if( field.getTypeDescriptor()!=null && field.getTypeDescriptor().isEnum() ) {
+ return javaType(field)+"."+defaultOption.getValue();
+ }
+ return defaultOption.getValue();
+ } else {
+ if( field.isNumberType() ) {
+ return "0";
+ }
+ if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
+ return "false";
+ }
+ return "null";
+ }
+ }
+
+ static final char HEX_TABLE[] = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ private String asJavaString(String value) {
+ StringBuilder sb = new StringBuilder(value.length()+2);
+ sb.append("\"");
+ for (int i = 0; i < value.length(); i++) {
+
+ char b = value.charAt(i);
+ switch (b) {
+ // Java does not recognize \a or \v, apparently.
+ case '\b': sb.append("\\b" ); break;
+ case '\f': sb.append("\\f" ); break;
+ case '\n': sb.append("\\n" ); break;
+ case '\r': sb.append("\\r" ); break;
+ case '\t': sb.append("\\t" ); break;
+ case '\\': sb.append("\\\\"); break;
+ case '\'': sb.append("\\\'"); break;
+ case '"' : sb.append("\\\""); break;
+ default:
+ if (b >= 0x20 && b <'Z') {
+ sb.append((char) b);
+ } else {
+ sb.append("\\u");
+ sb.append(HEX_TABLE[(b >>> 12) & 0x0F] );
+ sb.append(HEX_TABLE[(b >>> 8) & 0x0F] );
+ sb.append(HEX_TABLE[(b >>> 4) & 0x0F] );
+ sb.append(HEX_TABLE[b & 0x0F] );
+ }
+ break;
+ }
+
+ }
+ sb.append("\"");
+ return sb.toString();
+ }
+
+ private void generateEnum(EnumDescriptor ed) {
+ String uname = uCamel(ed.getName());
+
+ String staticOption = "static ";
+ if( multipleFiles && ed.getParent()==null ) {
+ staticOption="";
+ }
+
+ // TODO Auto-generated method stub
+ p();
+ p("public "+staticOption+"enum " +uname + " {");
+ indent();
+
+
+ p();
+ int counter=0;
+ for (EnumFieldDescriptor field : ed.getFields().values()) {
+ boolean last = counter+1 == ed.getFields().size();
+ p(field.getName()+"(\""+field.getName()+"\", "+field.getValue()+")"+(last?";":","));
+ counter++;
+ }
+ p();
+ p("private final String name;");
+ p("private final int value;");
+ p();
+ p("private "+uname+"(String name, int value) {");
+ p(" this.name = name;");
+ p(" this.value = value;");
+ p("}");
+ p();
+ p("public final int getNumber() {");
+ p(" return value;");
+ p("}");
+ p();
+ p("public final String toString() {");
+ p(" return name;");
+ p("}");
+ p();
+ p("public static "+uname+" valueOf(int value) {");
+ p(" switch (value) {");
+
+ // It's possible to define multiple ENUM fields with the same value..
+ // we only want to put the first one into the switch statement.
+ HashSet<Integer> values = new HashSet<Integer>();
+ for (EnumFieldDescriptor field : ed.getFields().values()) {
+ if( !values.contains(field.getValue()) ) {
+ p(" case "+field.getValue()+":");
+ p(" return "+field.getName()+";");
+ values.add(field.getValue());
+ }
+
+ }
+ p(" default:");
+ p(" return null;");
+ p(" }");
+ p("}");
+ p();
+
+
+ String createMessage = getOption(ed.getOptions(), "java_create_message", null);
+ if( "true".equals(createMessage) ) {
+
+ p("public Object createBean() {");
+ indent();
+ p("switch (this) {");
+ indent();
+ for (EnumFieldDescriptor field : ed.getFields().values()) {
+ p("case "+field.getName()+":");
+ String type = constantToUCamelCase(field.getName());
+ p(" return new "+type+"."+type+"Bean();");
+ }
+ p("default:");
+ p(" return null;");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ p();
+
+ generateParseDelegate(ed, "parseUnframed", "org.apache.activemq.protobuf.Buffer", "org.apache.activemq.protobuf.InvalidProtocolBufferException");
+ generateParseDelegate(ed, "parseFramed", "org.apache.activemq.protobuf.Buffer", "org.apache.activemq.protobuf.InvalidProtocolBufferException");
+ generateParseDelegate(ed, "parseUnframed", "byte[]", "org.apache.activemq.protobuf.InvalidProtocolBufferException");
+ generateParseDelegate(ed, "parseFramed", "byte[]", "org.apache.activemq.protobuf.InvalidProtocolBufferException");
+ generateParseDelegate(ed, "parseFramed", "org.apache.activemq.protobuf.CodedInputStream", "org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException");
+ generateParseDelegate(ed, "parseFramed", "java.io.InputStream", "org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException");
+ }
+
+ unindent();
+ p("}");
+ p();
+ }
+
+ private void generateParseDelegate(EnumDescriptor descriptor, String methodName, String inputType, String exceptions) {
+ p("public org.apache.activemq.protobuf.MessageBuffer " + methodName + "(" + inputType + " data) throws " + exceptions + " {");
+ indent();
+ p("switch (this) {");
+ indent();
+ for (EnumFieldDescriptor field : descriptor.getFields().values()) {
+ p("case "+field.getName()+":");
+ String type = constantToUCamelCase(field.getName());
+ p(" return "+type+"."+type+"Buffer."+methodName+"(data);");
+ }
+ p("default:");
+ p(" return null;");
+ unindent();
+ p("}");
+ unindent();
+ p("}");
+ p();
+ }
+
+
+
+ private String javaCollectionType(FieldDescriptor field) {
+ if( field.isInteger32Type() ) {
+ return "java.lang.Integer";
+ }
+ if( field.isInteger64Type() ) {
+ return "java.lang.Long";
+ }
+ if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) {
+ return "java.lang.Double";
+ }
+ if( field.getType() == FieldDescriptor.FLOAT_TYPE ) {
+ return "java.lang.Float";
+ }
+ if( field.getType() == FieldDescriptor.STRING_TYPE ) {
+ return "java.lang.String";
+ }
+ if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
+ return "org.apache.activemq.protobuf.Buffer";
+ }
+ if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
+ return "java.lang.Boolean";
+ }
+
+ TypeDescriptor descriptor = field.getTypeDescriptor();
+ return javaType(descriptor);
+ }
+
+ private String javaType(FieldDescriptor field) {
+ if( field.isInteger32Type() ) {
+ return "int";
+ }
+ if( field.isInteger64Type() ) {
+ return "long";
+ }
+ if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) {
+ return "double";
+ }
+ if( field.getType() == FieldDescriptor.FLOAT_TYPE ) {
+ return "float";
+ }
+ if( field.getType() == FieldDescriptor.STRING_TYPE ) {
+ return "java.lang.String";
+ }
+ if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
+ return "org.apache.activemq.protobuf.Buffer";
+ }
+ if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
+ return "boolean";
+ }
+
+ TypeDescriptor descriptor = field.getTypeDescriptor();
+ return javaType(descriptor);
+ }
+
+ private String javaType(TypeDescriptor descriptor) {
+ ProtoDescriptor p = descriptor.getProtoDescriptor();
+ if( p != proto ) {
+ // Try to keep it short..
+ String othePackage = javaPackage(p);
+ if( equals(othePackage,javaPackage(proto) ) ) {
+ return javaClassName(p)+"."+descriptor.getQName();
+ }
+ // Use the fully qualified class name.
+ return othePackage+"."+javaClassName(p)+"."+descriptor.getQName();
+ }
+ return descriptor.getQName();
+ }
+
+ private boolean equals(String o1, String o2) {
+ if( o1==o2 )
+ return true;
+ if( o1==null || o2==null )
+ return false;
+ return o1.equals(o2);
+ }
+
+ private String javaClassName(ProtoDescriptor proto) {
+ return getOption(proto.getOptions(), "java_outer_classname", uCamel(removeFileExtension(proto.getName())));
+ }
+
+ private boolean isMultipleFilesEnabled(ProtoDescriptor proto) {
+ return "true".equals(getOption(proto.getOptions(), "java_multiple_files", "false"));
+ }
+
+
+ private String javaPackage(ProtoDescriptor proto) {
+ String name = proto.getPackageName();
+ if( name!=null ) {
+ name = name.replace('-', '.');
+ name = name.replace('/', '.');
+ }
+ return getOption(proto.getOptions(), "java_package", name);
+ }
+
+
+ // ----------------------------------------------------------------
+ // Internal Helper methods
+ // ----------------------------------------------------------------
+
+ private void indent() {
+ indent++;
+ }
+
+ private void unindent() {
+ indent--;
+ }
+
+ private void p(String line) {
+ // Indent...
+ for (int i = 0; i < indent; i++) {
+ w.print(" ");
+ }
+ // Then print.
+ w.println(line);
+ }
+
+ private void p() {
+ w.println();
+ }
+
+ private String getOption(Map<String, OptionDescriptor> options, String optionName, String defaultValue) {
+ OptionDescriptor optionDescriptor = options.get(optionName);
+ if (optionDescriptor == null) {
+ return defaultValue;
+ }
+ return optionDescriptor.getValue();
+ }
+
+ static private String removeFileExtension(String name) {
+ return name.replaceAll("\\..*", "");
+ }
+
+ static private String uCamel(String name) {
+ boolean upNext=true;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) {
+ if( upNext ) {
+ c = Character.toUpperCase(c);
+ upNext=false;
+ }
+ sb.append(c);
+ } else {
+ upNext=true;
+ }
+ }
+ return sb.toString();
+ }
+
+ static private String lCamel(String name) {
+ if( name == null || name.length()<1 )
+ return name;
+ String uCamel = uCamel(name);
+ return uCamel.substring(0,1).toLowerCase()+uCamel.substring(1);
+ }
+
+
+ private String constantToUCamelCase(String name) {
+ boolean upNext=true;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) {
+ if( upNext ) {
+ c = Character.toUpperCase(c);
+ upNext=false;
+ } else {
+ c = Character.toLowerCase(c);
+ }
+ sb.append(c);
+ } else {
+ upNext=true;
+ }
+ }
+ return sb.toString();
+ }
+
+
+ private String constantCase(String name) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if( i!=0 && Character.isUpperCase(c) ) {
+ sb.append("_");
+ }
+ sb.append(Character.toUpperCase(c));
+ }
+ return sb.toString();
+ }
+
+ public File getOut() {
+ return out;
+ }
+
+ public void setOut(File outputDirectory) {
+ this.out = outputDirectory;
+ }
+
+ public File[] getPath() {
+ return path;
+ }
+
+ public void setPath(File[] path) {
+ this.path = path;
+ }
+
+}
Added: activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/CompilerException.java
URL: http://svn.apache.org/viewvc/activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/CompilerException.java?rev=745108&view=auto
==============================================================================
--- activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/CompilerException.java (added)
+++ activemq/activemq-protobuf/trunk/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/CompilerException.java Tue Feb 17 14:49:52 2009
@@ -0,0 +1,18 @@
+/**
+ *
+ */
+package org.apache.activemq.protobuf.compiler;
+
+import java.util.List;
+
+public class CompilerException extends Exception {
+ private final List<String> errors;
+
+ public CompilerException(List<String> errors) {
+ this.errors = errors;
+ }
+
+ public List<String> getErrors() {
+ return errors;
+ }
+}
\ No newline at end of file