Bug 1119 - Optimize generated range checks 83/9483/7
authorLadislav Borak <lborak@cisco.com>
Wed, 30 Jul 2014 21:56:02 +0000 (23:56 +0200)
committerLadislav Borak <lborak@cisco.com>
Fri, 1 Aug 2014 15:06:09 +0000 (17:06 +0200)
- moved initialization of range and length constraints list
  into static initialization block

Change-Id: I2f5631fceb0e776fe3172e9a05ee97b7fe81252b
Signed-off-by: Ladislav Borak <lborak@cisco.com>
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend

index 24d0a7fd6031f30b2410033337f7f6bef89f59f4..eb7b948c545283c6e7e3d162a202574365eb0723 100644 (file)
@@ -498,15 +498,15 @@ abstract class BaseTemplate {
             «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
             public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
                 «IF numberClass.equals(typeof(BigDecimal))»
-                    «lengthMethodBody(restrictions, numberClass, className, varName)»
+                    «lengthBody(restrictions, numberClass, className, varName)»
                 «ELSE»
-                    «lengthMethodBody(restrictions, typeof(BigInteger), className, varName)»
+                    «lengthBody(restrictions, typeof(BigInteger), className, varName)»
                 «ENDIF»
             }
         «ENDIF»
     '''
 
-    def private lengthMethodBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+    def private lengthBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
         if («varName» == null) {
             synchronized («className».class) {
                 if («varName» == null) {
@@ -526,9 +526,9 @@ abstract class BaseTemplate {
             «val number = returnType.importedNumber»
             public static «List.importedName»<«Range.importedName»<«number»>> «methodName»() {
                 «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
-                    «rangeMethodBody(restrictions, BigDecimal, className, varName)»
+                    «rangeBody(restrictions, BigDecimal, className, varName)»
                 «ELSE»
-                    «rangeMethodBody(restrictions, BigInteger, className, varName)»
+                    «rangeBody(restrictions, BigInteger, className, varName)»
                 «ENDIF»
             }
         «ENDIF»
@@ -539,15 +539,15 @@ abstract class BaseTemplate {
             «val returnType = properties.iterator.next.returnType»
             public static «List.importedName»<«Range.importedName»<«returnType.importedNumber»>> «methodName»() {
                 «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
-                    «rangeMethodBody(restrictions, BigDecimal, className, varName)»
+                    «rangeBody(restrictions, BigDecimal, className, varName)»
                 «ELSE»
-                    «rangeMethodBody(restrictions, BigInteger, className, varName)»
+                    «rangeBody(restrictions, BigInteger, className, varName)»
                 «ENDIF»
             }
         «ENDIF»
     '''
 
-    def private rangeMethodBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+    def private rangeBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
         if («varName» == null) {
             synchronized («className».class) {
                 if («varName» == null) {
@@ -576,7 +576,7 @@ abstract class BaseTemplate {
         return BigInteger.importedName
     }
 
-    def private String numericValue(Class<? extends Number> clazz, Object numberValue) {
+    def protected String numericValue(Class<? extends Number> clazz, Object numberValue) {
         val number = clazz.importedName;
         val value = numberValue.toString
         if (clazz.equals(typeof(BigInteger)) || clazz.equals(typeof(BigDecimal))) {
index e92f84e489ae1e3db0bea4faf4569b3ae2e8f304..afebd5846b156465d9ec7de1049124190696a7a1 100644 (file)
@@ -7,24 +7,28 @@
  */
 package org.opendaylight.yangtools.sal.java.api.generator
 
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.Lists
+import com.google.common.collect.Range
+import com.google.common.io.BaseEncoding
+import java.beans.ConstructorProperties
+import java.math.BigDecimal
+import java.math.BigInteger
+import java.util.ArrayList
+import java.util.Arrays
+import java.util.Collections
 import java.util.List
+import java.util.regex.Pattern
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants
 import org.opendaylight.yangtools.sal.binding.model.api.Constant
 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import java.util.ArrayList
-import java.util.Collections\rimport java.util.Arrays
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
-import com.google.common.collect.Range
-import java.util.regex.Pattern
-import com.google.common.io.BaseEncoding
-import java.beans.ConstructorProperties
-import com.google.common.collect.Lists
 
 /**
- * Template for generating JAVA class. 
+ * Template for generating JAVA class.
  */
 class ClassTemplate extends BaseTemplate {
 
@@ -33,23 +37,22 @@ class ClassTemplate extends BaseTemplate {
     protected val List<GeneratedProperty> parentProperties
     protected val Iterable<GeneratedProperty> allProperties;
     protected val Restrictions restrictions
-    
+
     /**
      * List of enumeration which are generated as JAVA enum type.
      */
     protected val List<Enumeration> enums
-    
+
     /**
      * List of constant instances which are generated as JAVA public static final attributes.
      */
     protected val List<Constant> consts
-    
+
     /**
      * List of generated types which are enclosed inside <code>genType</code>
      */
     protected val List<GeneratedType> enclosedGeneratedTypes;
     
-    
     protected val GeneratedTransferObject genTO;
 
     /**
@@ -78,7 +81,6 @@ class ClassTemplate extends BaseTemplate {
         this.enclosedGeneratedTypes = genType.enclosedTypes
     }
 
-
     /**
      * Generates JAVA class source code (class body only).
      * 
@@ -88,7 +90,6 @@ class ClassTemplate extends BaseTemplate {
         return generateBody(true)
     }
 
-
     override protected body() {
         generateBody(false);
     }
@@ -107,9 +108,14 @@ class ClassTemplate extends BaseTemplate {
             «enumDeclarations»
             «constantsDeclarations»
             «generateFields»
-
-            «constructors»
             
+            «IF restrictions != null && (!restrictions.rangeConstraints.nullOrEmpty || 
+                !restrictions.lengthConstraints.nullOrEmpty)»
+            «generateConstraints»
+            
+            «ENDIF»
+            «constructors»
+
             «defaultInstance»
 
             «FOR field : properties SEPARATOR "\n"»
@@ -125,13 +131,30 @@ class ClassTemplate extends BaseTemplate {
 
             «generateToString(genTO.toStringIdentifiers)»
 
-            «generateLengthMethod("length", genTO, genTO.importedName, "_length")»
+            «generateLengthMethod("length", "_length")»
 
-            «generateRangeMethod("range", genTO.restrictions, genTO.importedName, "_range", allProperties
+            «generateRangeMethod("range", "_range"
 
         }
     '''
 
+    def private generateLengthMethod(String methodName, String varName) '''
+        «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
+            «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
+            public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
+                return «varName»;
+            }
+        «ENDIF»
+    '''
+
+    def private generateRangeMethod(String methodName, String varName) '''
+        «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
+            «val returnType = allProperties.iterator.next.returnType»
+            public static «List.importedName»<«Range.importedName»<«returnType.importedNumber»>> «methodName»() {
+                return «varName»;
+            }
+        «ENDIF»
+    '''
 
     /**
      * Template method which generates inner classes inside this interface.
@@ -144,13 +167,12 @@ class ClassTemplate extends BaseTemplate {
                 «IF (innerClass instanceof GeneratedTransferObject)»
                     «val classTemplate = new ClassTemplate(innerClass as GeneratedTransferObject)»
                     «classTemplate.generateAsInnerClass»
-                    
+
                 «ENDIF»
             «ENDFOR»
         «ENDIF»
     '''
-    
-    
+
     def protected constructors() '''
         «IF genTO.unionType»
             «genUnionConstructor»
@@ -165,6 +187,55 @@ class ClassTemplate extends BaseTemplate {
         «ENDIF»
     '''
 
+    def private generateConstraints() '''
+        static {
+            «IF !restrictions.rangeConstraints.nullOrEmpty»
+            «generateRangeConstraints»
+            «ENDIF»
+            «IF !restrictions.lengthConstraints.nullOrEmpty»
+            «generateLengthConstraints»
+            «ENDIF»
+        }
+    '''
+
+    private def generateRangeConstraints() '''
+        «IF !allProperties.nullOrEmpty»
+            «val returnType = allProperties.iterator.next.returnType»
+            «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
+                «rangeBody(restrictions, BigDecimal, genTO.importedName, "_range")»
+            «ELSE»
+                «rangeBody(restrictions, BigInteger, genTO.importedName, "_range")»
+            «ENDIF»
+        «ENDIF»
+    '''
+
+    private def rangeBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+        «ImmutableList.importedName».Builder<«Range.importedName»<«numberClass.importedName»>> builder = «ImmutableList.importedName».builder();
+        «FOR r : restrictions.rangeConstraints»
+            builder.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
+        «ENDFOR»
+        «varName» = builder.build();
+    '''
+
+    private def lengthBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+        «ImmutableList.importedName».Builder<«Range.importedName»<«numberClass.importedName»>> builder = «ImmutableList.importedName».builder();
+        «FOR r : restrictions.lengthConstraints»
+            builder.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
+        «ENDFOR»
+        «varName» = builder.build();
+    '''
+
+    private def generateLengthConstraints() '''
+        «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
+            «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
+            «IF numberClass.equals(typeof(BigDecimal))»
+                «lengthBody(restrictions, numberClass, genTO.importedName, "_length")»
+            «ELSE»
+                «lengthBody(restrictions, typeof(BigInteger), genTO.importedName, "_length")»
+            «ENDIF»
+        «ENDIF»
+    '''
+
     def protected allValuesConstructor() '''
     «IF genTO.typedef && !allProperties.empty && allProperties.size == 1 && allProperties.get(0).name.equals("value")»
         @«ConstructorProperties.importedName»("value")
@@ -180,6 +251,7 @@ class ClassTemplate extends BaseTemplate {
             this.«p.fieldName» = «p.fieldName»;
         «ENDFOR»
     }
+    
     '''
 
     def protected genUnionConstructor() '''
@@ -296,7 +368,7 @@ class ClassTemplate extends BaseTemplate {
             ENDFOR»«
         ENDIF
     »'''
-    
+
     /**
      * Template method which generates JAVA enum type.
      * 
@@ -369,10 +441,10 @@ class ClassTemplate extends BaseTemplate {
             «val prop = getPropByName("value")»
             «IF prop != null»
                 «IF !(restrictions.lengthConstraints.empty)»
-                    private static «List.importedName»<«Range.importedName»<«prop.returnType.importedNumber»>> _length;
+                    private static final «List.importedName»<«Range.importedName»<«prop.returnType.importedNumber»>> _length;
                 «ENDIF»
                 «IF !(restrictions.rangeConstraints.empty)»
-                    private static «List.importedName»<«Range.importedName»<«prop.returnType.importedNumber»>> _range;
+                    private static final «List.importedName»<«Range.importedName»<«prop.returnType.importedNumber»>> _range;
                 «ENDIF»
             «ENDIF»
         «ENDIF»