| /** |
| * 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=""; |
| } |
| |
| String extendsClause = " extends org.apache.activemq.protobuf.PBMessage<"+className+"."+beanClassName+", "+className+"."+bufferClassName+">"; |
| for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { |
| String name = uCamel(enumFeild.getParent().getName()); |
| name = name+"."+name+"Creatable"; |
| extendsClause += ", "+name; |
| } |
| |
| p(staticOption+"public interface " + className + extendsClause +" {"); |
| 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); |
| |
| generateReadWriteExternal(m); |
| |
| for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { |
| String enumName = uCamel(enumFeild.getParent().getName()); |
| p("public "+enumName+" to"+enumName+"() {"); |
| indent(); |
| p("return "+enumName+"."+enumFeild.getName()+";"); |
| unindent(); |
| p("}"); |
| p(); |
| } |
| |
| unindent(); |
| p("}"); |
| p(); |
| |
| p("static public final class "+bufferClassName+" implements org.apache.activemq.protobuf.MessageBuffer<"+className+"."+beanClassName+", "+className+"."+bufferClassName+">, "+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); |
| |
| p("public boolean frozen() {"); |
| indent(); |
| p("return true;"); |
| unindent(); |
| p("}"); |
| |
| for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { |
| String enumName = uCamel(enumFeild.getParent().getName()); |
| p("public "+enumName+" to"+enumName+"() {"); |
| indent(); |
| p("return "+enumName+"."+enumFeild.getName()+";"); |
| unindent(); |
| p("}"); |
| p(); |
| } |
| |
| 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("assert deepFreeze();"); |
| unindent(); |
| p("}"); |
| p("return frozen;"); |
| unindent(); |
| p("}"); |
| p(); |
| p("private boolean deepFreeze() {"); |
| indent(); |
| p("frozen.serializedSizeUnframed();"); |
| p("return true;"); |
| 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(); |
| String override = getOption(field.getOptions(), "java_override_type", null); |
| if( "AsciiBuffer".equals(override) ) { |
| p(setter + "(new org.apache.activemq.protobuf.AsciiBuffer(input.readBytes()));"); |
| } else if( "UTF8Buffer".equals(override) ) { |
| p(setter + "(new org.apache.activemq.protobuf.UTF8Buffer(input.readBytes()));"); |
| } else { |
| 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 generateReadWriteExternal(MessageDescriptor m) { |
| |
| p("public void readExternal(java.io.DataInput in) throws java.io.IOException {"); |
| indent(); |
| p("assert frozen==null : org.apache.activemq.protobuf.MessageBufferSupport.FORZEN_ERROR_MESSAGE;"); |
| p("bean = this;"); |
| p("frozen = null;"); |
| |
| for (FieldDescriptor field : m.getFields().values()) { |
| String lname = lCamel(field.getName()); |
| String type = javaType(field); |
| boolean repeated = field.getRule()==FieldDescriptor.REPEATED_RULE; |
| |
| // Create the fields.. |
| if( repeated ) { |
| p("{"); |
| indent(); |
| p("int size = in.readShort();"); |
| p("if( size>=0 ) {"); |
| indent(); |
| p("f_"+lname+" = new java.util.ArrayList<" + javaCollectionType(field) + ">(size);"); |
| p("for(int i=0; i<size; i++) {"); |
| indent(); |
| if( field.isInteger32Type() ) { |
| p("f_"+lname+".add(in.readInt());"); |
| } else if( field.isInteger64Type() ) { |
| p("f_"+lname+".add(in.readLong());"); |
| } else if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) { |
| p("f_"+lname+".add(in.readDouble());"); |
| } else if( field.getType() == FieldDescriptor.FLOAT_TYPE ) { |
| p("f_"+lname+".add(in.readFloat());"); |
| } else if( field.getType() == FieldDescriptor.BOOL_TYPE ) { |
| p("f_"+lname+".add(in.readBoolean());"); |
| } else if( field.getType() == FieldDescriptor.STRING_TYPE ) { |
| p("f_"+lname+".add(in.readUTF());"); |
| } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| p("byte b[] = new byte[in.readInt()];"); |
| p("in.readFully(b);"); |
| p("f_"+lname+".add(new "+type+"(b));"); |
| } else if (field.getTypeDescriptor().isEnum() ) { |
| p("f_"+lname+".add(" + type + ".valueOf(in.readShort()));"); |
| } else { |
| p(""+type+"."+type+"Bean o = new "+type+"."+type+"Bean();"); |
| p("o.readExternal(in);"); |
| p("f_"+lname+".add(o);"); |
| } |
| unindent(); |
| p("}"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("f_"+lname+" = null;"); |
| unindent(); |
| p("}"); |
| unindent(); |
| p("}"); |
| |
| } else { |
| if( field.isInteger32Type() ) { |
| p("f_"+lname+" = in.readInt();"); |
| p("b_"+lname+" = true;"); |
| } else if( field.isInteger64Type() ) { |
| p("f_"+lname+" = in.readLong();"); |
| p("b_"+lname+" = true;"); |
| } else if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) { |
| p("f_"+lname+" = in.readDouble();"); |
| p("b_"+lname+" = true;"); |
| } else if( field.getType() == FieldDescriptor.FLOAT_TYPE ) { |
| p("f_"+lname+" = in.readFloat();"); |
| p("b_"+lname+" = true;"); |
| } else if( field.getType() == FieldDescriptor.BOOL_TYPE ) { |
| p("f_"+lname+" = in.readBoolean();"); |
| p("b_"+lname+" = true;"); |
| } else if( field.getType() == FieldDescriptor.STRING_TYPE ) { |
| p("if( in.readBoolean() ) {"); |
| indent(); |
| p("f_"+lname+" = in.readUTF();"); |
| p("b_"+lname+" = true;"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("f_"+lname+" = null;"); |
| p("b_"+lname+" = false;"); |
| unindent(); |
| p("}"); |
| } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| p("{"); |
| indent(); |
| p("int size = in.readInt();"); |
| p("if( size>=0 ) {"); |
| indent(); |
| p("byte b[] = new byte[size];"); |
| p("in.readFully(b);"); |
| p("f_"+lname+" = new "+type+"(b);"); |
| p("b_"+lname+" = true;"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("f_"+lname+" = null;"); |
| p("b_"+lname+" = false;"); |
| unindent(); |
| p("}"); |
| unindent(); |
| p("}"); |
| } else if (field.getTypeDescriptor().isEnum() ) { |
| p("if( in.readBoolean() ) {"); |
| indent(); |
| p("f_"+lname+" = " + type + ".valueOf(in.readShort());"); |
| p("b_"+lname+" = true;"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("f_"+lname+" = null;"); |
| p("b_"+lname+" = false;"); |
| unindent(); |
| p("}"); |
| } else { |
| p("if( in.readBoolean() ) {"); |
| indent(); |
| p(""+type+"."+type+"Bean o = new "+type+"."+type+"Bean();"); |
| p("o.readExternal(in);"); |
| p("f_"+lname+" = o;"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("f_"+lname+" = null;"); |
| unindent(); |
| p("}"); |
| } |
| } |
| } |
| |
| unindent(); |
| p("}"); |
| p(); |
| p("public void writeExternal(java.io.DataOutput out) throws java.io.IOException {"); |
| indent(); |
| for (FieldDescriptor field : m.getFields().values()) { |
| String lname = lCamel(field.getName()); |
| boolean repeated = field.getRule()==FieldDescriptor.REPEATED_RULE; |
| |
| // Create the fields.. |
| if( repeated ) { |
| p("if( bean.f_"+lname+"!=null ) {"); |
| indent(); |
| p("out.writeShort(bean.f_"+lname+".size());"); |
| p("for(" + javaCollectionType(field) + " o : bean.f_"+lname+") {"); |
| indent(); |
| |
| if( field.isInteger32Type() ) { |
| p("out.writeInt(o);"); |
| } else if( field.isInteger64Type() ) { |
| p("out.writeLong(o);"); |
| } else if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) { |
| p("out.writeDouble(o);"); |
| } else if( field.getType() == FieldDescriptor.FLOAT_TYPE ) { |
| p("out.writeFloat(o);"); |
| } else if( field.getType() == FieldDescriptor.BOOL_TYPE ) { |
| p("out.writeBoolean(o);"); |
| } else if( field.getType() == FieldDescriptor.STRING_TYPE ) { |
| p("out.writeUTF(o);"); |
| } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| p("out.writeInt(o.getLength());"); |
| p("out.write(o.getData(), o.getOffset(), o.getLength());"); |
| } else if (field.getTypeDescriptor().isEnum() ) { |
| p("out.writeShort(o.getNumber());"); |
| } else { |
| p("o.copy().writeExternal(out);"); |
| } |
| unindent(); |
| p("}"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("out.writeShort(-1);"); |
| unindent(); |
| p("}"); |
| |
| } else { |
| if( field.isInteger32Type() ) { |
| p("out.writeInt(bean.f_"+lname+");"); |
| } else if( field.isInteger64Type() ) { |
| p("out.writeLong(bean.f_"+lname+");"); |
| } else if( field.getType() == FieldDescriptor.DOUBLE_TYPE ) { |
| p("out.writeDouble(bean.f_"+lname+");"); |
| } else if( field.getType() == FieldDescriptor.FLOAT_TYPE ) { |
| p("out.writeFloat(bean.f_"+lname+");"); |
| } else if( field.getType() == FieldDescriptor.BOOL_TYPE ) { |
| p("out.writeBoolean(bean.f_"+lname+");"); |
| } else if( field.getType() == FieldDescriptor.STRING_TYPE ) { |
| p("if( bean.f_"+lname+"!=null ) {"); |
| indent(); |
| p("out.writeBoolean(true);"); |
| p("out.writeUTF(bean.f_"+lname+");"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("out.writeBoolean(false);"); |
| unindent(); |
| p("}"); |
| } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| p("if( bean.f_"+lname+"!=null ) {"); |
| indent(); |
| p("out.writeInt(bean.f_"+lname+".getLength());"); |
| p("out.write(bean.f_"+lname+".getData(), bean.f_"+lname+".getOffset(), bean.f_"+lname+".getLength());"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("out.writeInt(-1);"); |
| unindent(); |
| p("}"); |
| } else if (field.getTypeDescriptor().isEnum() ) { |
| p("if( bean.f_"+lname+"!=null ) {"); |
| indent(); |
| p("out.writeBoolean(true);"); |
| p("out.writeShort(bean.f_"+lname+".getNumber());"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("out.writeBoolean(false);"); |
| unindent(); |
| p("}"); |
| } else { |
| p("if( bean.f_"+lname+"!=null ) {"); |
| indent(); |
| p("out.writeBoolean(true);"); |
| p("bean.f_"+lname+".copy().writeExternal(out);"); |
| unindent(); |
| p("} else {"); |
| indent(); |
| p("out.writeBoolean(false);"); |
| unindent(); |
| p("}"); |
| } |
| } |
| } |
| |
| 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 "+javaType(field)+"("+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 interface "+uname+"Creatable {"); |
| indent(); |
| p(""+uname+" to"+uname+"();"); |
| unindent(); |
| p("}"); |
| p(); |
| |
| p("public "+uname+"Creatable createBean() {"); |
| indent(); |
| p("switch (this) {"); |
| indent(); |
| for (EnumFieldDescriptor field : ed.getFields().values()) { |
| p("case "+field.getName()+":"); |
| String type = field.getAssociatedType().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 ) { |
| // TODO: support handling string fields as buffers. |
| // String override = getOption(field.getOptions(), "java_override_type", null); |
| // if( "AsciiBuffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.AsciiBuffer"; |
| // } else if( "UTF8Buffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.UTF8Buffer"; |
| // } else if( "Buffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.Buffer"; |
| // } else { |
| return "java.lang.String"; |
| // } |
| } |
| if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| String override = getOption(field.getOptions(), "java_override_type", null); |
| if( "AsciiBuffer".equals(override) ) { |
| return "org.apache.activemq.protobuf.AsciiBuffer"; |
| } else if( "UTF8Buffer".equals(override) ) { |
| return "org.apache.activemq.protobuf.UTF8Buffer"; |
| } else { |
| 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 ) { |
| // TODO: support handling string fields as buffers. |
| // String override = getOption(field.getOptions(), "java_override_type", null); |
| // if( "AsciiBuffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.AsciiBuffer"; |
| // } else if( "UTF8Buffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.UTF8Buffer"; |
| // } else if( "Buffer".equals(override) ) { |
| // return "org.apache.activemq.protobuf.Buffer"; |
| // } else { |
| return "java.lang.String"; |
| // } |
| } |
| if( field.getType() == FieldDescriptor.BYTES_TYPE ) { |
| String override = getOption(field.getOptions(), "java_override_type", null); |
| if( "AsciiBuffer".equals(override) ) { |
| return "org.apache.activemq.protobuf.AsciiBuffer"; |
| } else if( "UTF8Buffer".equals(override) ) { |
| return "org.apache.activemq.protobuf.UTF8Buffer"; |
| } else { |
| 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; |
| } |
| |
| } |