mbeckerle commented on code in PR #1192:
URL: https://github.com/apache/daffodil/pull/1192#discussion_r1539809309
##########
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 this was just avoiding boxes on the boxes on the boxes. Scala's
decimal is built on java's decimal so one more layer of object between the
actual data and operations on it. We did not strictly speaking need the
additional functionality of the scala decimal class, so we decided to go with
Java's boxed number types as our representation types in the infoset. I rather
wish we had gone with ULong for xs:unsignedLong because it is far more
efficient, but this decision is 10 years ago and probably before we learned of
the ULong library.
--
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]