stevedlawrence commented on code in PR #1192:
URL: https://github.com/apache/daffodil/pull/1192#discussion_r1539718169


##########
daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala:
##########
@@ -960,12 +962,73 @@ trait ElementBase
     typeDef.optRestriction.flatMap { _.enumerationValues }
   }
 
+  final lazy val length: java.math.BigDecimal = {
+    Assert.invariant(hasLength)
+    schemaDefinitionUnless(
+      isSimpleType,
+      "Facet length is allowed only on simple types or types derived from 
simple types.",
+    )
+    typeDef match {
+      case _ if hasRepType => {
+        // this length is only used for the length of the representation. The
+        // values used for facet restrictions during limited validation come 
from elsewhere
+        repTypeElementDecl.length
+      }
+      case prim: PrimitiveType => {
+        val pt = prim.primType
+        schemaDefinitionWhen(
+          (pt == PrimType.String || pt == PrimType.HexBinary) && lengthKind == 
LengthKind.Implicit,
+          "Facet length must be defined for type %s with 
lengthKind='implicit'",
+          pt.name,
+        )
+        //
+        // We handle text numbers by getting a stringValue first, then
+        // we convert to the number type.
+        //
+        // This means we cannot check and SDE here on incorrect simple type.
+        zeroBD
+      }
+      case st: SimpleTypeDefBase if st.optRestriction.isDefined => {
+        val r = st.optRestriction.get
+        val pt = st.primType
+        val typeOK = pt == PrimType.String || pt == PrimType.HexBinary
+        schemaDefinitionWhen(
+          !typeOK && hasLength,
+          "Facet length is not allowed on types derived from type %s.\nIt is 
allowed only on types derived from string and hexBinary.",
+          pt.name,
+        )
+        val res = (hasLength, lengthKind) match {
+          case (false, LengthKind.Implicit) =>
+            SDE(
+              "When lengthKind='implicit', length facet must be specified.",
+            )
+          case (true, _) => r.lengthValue
+          case (false, _) => zeroBD
+          case _ => Assert.impossible()
+        }
+        res
+      }
+      case st: SimpleTypeDefBase => {
+        Assert.invariant(st.optRestriction.isEmpty)
+        zeroBD
+      }
+    }
+  }
+
   /**
    * Compute minLength and maxLength together to share error-checking
    * and case dispatch that would otherwise have to be repeated.
+   *
+   * Also set them to the value of length, in the case we've used the length 
facet
    */
-  final lazy val (minLength: java.math.BigDecimal, maxLength: 
java.math.BigDecimal) =
-    computeMinMaxLength
+  final lazy val (minLength: java.math.BigDecimal, maxLength: 
java.math.BigDecimal) = {
+    // if hasLength is true, and min/maxLength is queried, set it to length
+    if (hasLength) {
+      (length, length)
+    } else {
+      computeMinMaxLength
+    }
+  }
   // TODO: why are we using java.math.BigDecimal, when scala has a much
   // nicer decimal class?

Review Comment:
   I think we moved away from Scala types in most cases a while ago. I don't 
remember why, but for example all of our Infoset primitives just java types. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to