This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new 17f3fa8a1 Remove dfdlx:inputTypeCalc and dfdlx:outputTypeCalc
17f3fa8a1 is described below
commit 17f3fa8a1206f8801ab96a262f2219fb3eb6c72f
Author: Steve Lawrence <[email protected]>
AuthorDate: Fri Aug 18 07:50:56 2023 -0400
Remove dfdlx:inputTypeCalc and dfdlx:outputTypeCalc
This removes the dfdlx:inputTypeCalc and dfdlx:outputTypeCalc properties
and DPath functions. This allows for removal of a number of related
member variables and functions used only by the expression type calc
functions. For example, the typeCalcMap is only used by the functions to
lookup a calculator by QName at runtime. All type calculators are known
statically at compile time, so everything related to runtime type
calculator maps goes away.
Also does some minor refactoring:
- Moves code around so similar logic is all in one place or removes
conditionals
- Changes a tuple where only element has a meaningful value to an Either
so we enforce that restriction
- Fixes typo in IdentityTypeCalc name
- Changes some error messages so they are a bit more less developer
centric
Deprecation/Compatibility:
The dfdlx:inputTypeCalc and dfdlx:outputTypeCalc properties and
functions have been removed. Instead, one should use dfdlx:repType with
dfdlx:repValues and dfdlx:repValueRanges.
DAFFODIL-2211
---
.../apache/daffodil/core/dpath/Expression.scala | 73 -----
.../core/dsom/AnnotatedSchemaComponent.scala | 8 -
.../daffodil/core/dsom/SchemaComponent.scala | 1 -
.../org/apache/daffodil/core/dsom/SchemaSet.scala | 35 +--
.../apache/daffodil/core/dsom/SimpleTypes.scala | 184 ++++-------
.../grammar/primitives/PrimitivesExpressions.scala | 6 -
.../core/runtime1/ElementBaseRuntime1Mixin.scala | 1 -
.../core/runtime1/SchemaSetRuntime1Mixin.scala | 11 +-
.../core/runtime1/SimpleTypeRuntime1Mixin.scala | 8 -
.../resources/org/apache/daffodil/xsd/dfdlx.xsd | 6 -
.../runtime1/dpath/DFDLXTypeCalcFunctions.scala | 56 ----
.../apache/daffodil/runtime1/dpath/DState.scala | 15 -
.../runtime1/dsom/CompiledExpression1.scala | 14 -
.../daffodil/runtime1/processors/RuntimeData.scala | 2 -
.../runtime1/processors/SchemaSetRuntimeData.scala | 2 -
.../runtime1/processors/TypeCalculator.scala | 346 +++++----------------
.../parsers/ExpressionEvaluatingParsers.scala | 1 -
.../daffodil/extensions/enum/enumInvalid.tdml | 46 +++
.../org/apache/daffodil/extensions/enum/enums.tdml | 41 +++
.../type_calc/inputTypeCalcExpression.tdml | 125 --------
.../type_calc/typeCalcFunctionErrors.tdml | 162 ----------
.../extensions/type_calc/typeCalcFunctions.tdml | 263 ----------------
.../org/apache/daffodil/extensions/TestEnums.scala | 5 +
.../extensions/TestInputTypeValueCalc.scala | 50 ---
24 files changed, 230 insertions(+), 1231 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
index 65424806a..3a4871f96 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
@@ -2051,35 +2051,6 @@ case class FunctionCallExpression(functionQNameString:
String, expressions: List
// Begin DFDLX functions
- // Begin TypeValueCalc related functions
- case (RefQName(_, "inputTypeCalc", DFDLX), args) => {
- val typeCalc = lookupTypeCalculator(args(0), true, false)
- FNTwoArgsExprInferedArgType(
- functionQNameString,
- functionQName,
- args,
- typeCalc.dstType,
- NodeInfo.String,
- typeCalc.srcType,
- DFDLXInputTypeCalc(_, typeCalc),
- )
- }
-
- case (RefQName(_, "outputTypeCalc", DFDLX), args) => {
- val typeCalc = lookupTypeCalculator(args(0), false, true)
- FNTwoArgsExprInferedArgType(
- functionQNameString,
- functionQName,
- args,
- typeCalc.srcType,
- NodeInfo.String,
- typeCalc.dstType,
- DFDLXOutputTypeCalc(_, typeCalc),
- )
- }
-
- // End typeValueCalc related functions
-
case (RefQName(_, "doubleFromRawLong", DFDLX), args) => {
FNOneArgExpr(
functionQNameString,
@@ -2309,50 +2280,6 @@ case class FunctionCallExpression(functionQNameString:
String, expressions: List
funcObj
}
- def lookupTypeCalculator(
- typeCalcExpr: Expression,
- requiresParse: Boolean,
- requiresUnparse: Boolean,
- ): TypeCalculator = {
- /*
- * Every function that currently uses this defines the type calculator
- * as their first arguement.
- * We still take the calculators name as an arguement to avoid relying on
this
- * fact.
- */
- Assert.invariant(typeCalcExpr == expressions(0))
- /*
- * This lookup needs to occur before the main type-checker runs, because
it is
- * used to determine the type of this expression.
- * As a result, we must do some type checking manually
- * Also, we insist that typeCalcExpr is a constant, which is not even
- * a concept that the type checker has
- */
- if (typeCalcExpr.inherentType != NodeInfo.String) {
- SDE("The type calculator name argument must be a constant string")
- }
- val qname = typeCalcExpr match {
- case typeCalcName: LiteralExpression =>
typeCalcName.v.asInstanceOf[String]
- case _ => SDE("The type calculator name argument must be a constant
string")
- }
- val refType = QName
- .resolveRef(qname, compileInfo.namespaces,
tunable.unqualifiedPathStepPolicy)
- .get
- .toGlobalQName
- val typeCalculator = compileInfo.typeCalcMap.get(refType) match {
- case None => SDE("Simple type %s does not exist or does not have a
repType", refType)
- case Some(x) => x
- }
- if (requiresParse && !typeCalculator.supportsParse) {
- SDE("The type calculator defined by %s does not define an
inputValueCalc.", qname)
- }
- if (requiresUnparse && !typeCalculator.supportsUnparse) {
- SDE("The type calculator defined by %s does not define an
outputValueCalc.", qname)
- }
- typeCalculator.initialize()
- typeCalculator
- }
-
}
abstract class FunctionCallBase(
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/AnnotatedSchemaComponent.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/AnnotatedSchemaComponent.scala
index ac47a4af0..29ce4a8cc 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/AnnotatedSchemaComponent.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/AnnotatedSchemaComponent.scala
@@ -46,12 +46,6 @@ import org.apache.daffodil.lib.xml.XMLUtils
* All "real" terms are able to resolve properties. Most other objects just
contribute
* properties to the mix, but they are not points where properties are
* used to generate processors.
- *
- * EnumerationFactory and SimpleTypeDefFactory are the oddballs out. In
addition to
- * being used to generate processors, these classes our also used to generate
abstract
- * TypeCalculators, which are not necessarily attached to any particular
element, nor
- * used to generate any processor (for instance, there may be a
globalSimpleType whose
- * only purpose is to define a TypeCalculator for use in DPath expressions)
*/
object ResolvesProperties {
@@ -64,8 +58,6 @@ object ResolvesProperties {
val localOnlyProperties = Seq(
"choiceBranchKey",
"hiddenGroupRef",
- "inputTypeCalc",
- "outputTypeCalc",
"repType",
"repValueRanges",
"repValues",
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponent.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponent.scala
index 1dbc156e6..e9eab707d 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponent.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaComponent.scala
@@ -82,7 +82,6 @@ trait SchemaComponent
path,
schemaFileLocation,
tunable.unqualifiedPathStepPolicy,
- schemaSet.typeCalcMap,
)
}
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
index c0d61e604..88dd0aa2d 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SchemaSet.scala
@@ -37,7 +37,6 @@ import org.apache.daffodil.lib.xml.NS
import org.apache.daffodil.lib.xml.XMLUtils
import org.apache.daffodil.lib.xml._
import org.apache.daffodil.runtime1.dpath.NodeInfo
-import
org.apache.daffodil.runtime1.processors.TypeCalculatorCompiler.TypeCalcMap
object SchemaSet {
def apply(
@@ -120,7 +119,6 @@ final class SchemaSet private (
override lazy val tunable = tunables
- requiredEvaluationsAlways(typeCalcMap)
requiredEvaluationsAlways(root)
requiredEvaluationsAlways(checkForDuplicateTopLevels())
@@ -221,19 +219,6 @@ final class SchemaSet private (
lazy val globalSimpleTypeDefs: Seq[GlobalSimpleTypeDef] =
schemas.flatMap(_.globalSimpleTypeDefs)
- /**
- * For simple types defs, get those that particpate
- * in type calculation.
- */
- lazy val typeCalcMap: TypeCalcMap = {
- // Just take all global simple type defs for now. Not just "in use".
- // filter them by whether they have a typeCalculator
- val factories = globalSimpleTypeDefs
- val withCalc = factories.filter(_.optTypeCalculator.isDefined)
- val mappings = withCalc.map(st => (st.globalQName,
st.optTypeCalculator.get))
- mappings.toMap
- }
-
/**
* For checking uniqueness of global definitions in their namespaces
*/
@@ -662,12 +647,10 @@ final class SchemaSet private (
private lazy val startingGlobalComponents: Seq[SchemaComponent] = {
root +: {
- // always need the simple type defs so we can ask for their
- // repTypeElements as part of constructing the complete object graph.
- // The inputTypeCalc/outputTypeCalc functions take
- // The QName of a simple type. By just always obtaining all the simple
types defs
- // we insure the quasi-elements used by them are always constructed, and
names
- // are resolvable.
+ // always need the simple type defs so we can ask for their repType
elements as part of
+ // constructing the complete object graph. By just always obtaining all
the simple types
+ // defs we insure the quasi-elements used by them are always
constructed, and names are
+ // resolvable.
allSchemaDocuments.flatMap { sd: SchemaDocument =>
sd.globalSimpleTypeDefs
} ++ {
@@ -711,15 +694,7 @@ class TransitiveClosureSchemaComponents private () extends
TransitiveClosure[Sch
e.typeDef match {
case std: SimpleTypeDefBase => Seq(std)
case ctd: ComplexTypeBase => Seq(ctd)
- case pt: PrimitiveType => {
- // An element decl with primitive type can still reference a
simple type by way
- // of dfdl:inputValueCalc that calls
dfdlx:inputTypeCalc('QNameOfType', ....)
- //
- // This is covered because the QNameOfType must be a
GlobalSimpleTypeDef and
- // those will always be part of all components and their type
calcs will be
- // checked.
- Nil
- }
+ case pt: PrimitiveType => Nil
}
case m: ModelGroup => m.groupMembers
case st: SimpleTypeDefBase =>
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
index 5b36e39cc..838c9e4be 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/SimpleTypes.scala
@@ -25,13 +25,10 @@ import
org.apache.daffodil.core.runtime1.SimpleTypeRuntime1Mixin
import org.apache.daffodil.lib.cookers.IntRangeCooker
import org.apache.daffodil.lib.cookers.RepValueCooker
import org.apache.daffodil.lib.exceptions.Assert
-import org.apache.daffodil.lib.schema.annotation.props.Found
import org.apache.daffodil.lib.schema.annotation.props.gen.ParseUnparsePolicy
import org.apache.daffodil.lib.util.Misc
-import org.apache.daffodil.lib.xml.GlobalQName
import org.apache.daffodil.lib.xml.QName
import org.apache.daffodil.lib.xml.RefQName
-import org.apache.daffodil.lib.xml.XMLUtils
import org.apache.daffodil.runtime1.dpath.InvalidPrimitiveDataException
import org.apache.daffodil.runtime1.dpath.NodeInfo
import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
@@ -39,7 +36,6 @@ import org.apache.daffodil.runtime1.infoset.DataValue
import org.apache.daffodil.runtime1.infoset.DataValue.DataValueBigInt
import org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitive
import
org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitiveNullable
-import org.apache.daffodil.runtime1.processors.IdentifyTypeCalculator
import org.apache.daffodil.runtime1.processors.RangeBound
import org.apache.daffodil.runtime1.processors.RepValueSet
import org.apache.daffodil.runtime1.processors.RepValueSetCompiler
@@ -312,40 +308,63 @@ abstract class SimpleTypeDefBase(xml: Node,
lexicalParent: SchemaComponent)
}
}
- lazy val optInputTypeCalc = findPropertyOption("inputTypeCalc",
expressionAllowed = true)
- lazy val optOutputTypeCalc = findPropertyOption("outputTypeCalc",
expressionAllowed = true)
-
+ /**
+ * The repType is a QName that resolves to a simple used to hang properties
that define the
+ * physical representation of this element. When used, it is because we want
to convert the
+ * physical representation to something else that actually ends up in the
infoset, usually
+ * with a different logical type. For example, we may want to convert a
numeric physical
+ * representation to string logical representation for the infoset. This
could be done using
+ * multiple elements and input/outputValueCalc, but using repType allows it
to be done by
+ * Daffodil. The task to convert a physical type to a logical type during
parse (or in reverse
+ * during unparse) is done via a TypeCalculator. The goal of this
optTypeCalculator is to
+ * inspect the various properties (e.g. repType, enumeration, unions,
repValues,
+ * repValueRanges) and create a TypeCalculator that does the necessary
conversions. This type
+ * calculator will later be provided to a parser/unparser to be evaluated at
runtime after the
+ * physical representation is parsed or prior to being unparsed.
+ */
lazy val optTypeCalculator: Option[TypeCalculator] = LV('optTypeCalculator) {
optRepType.flatMap(repType => {
val srcType = repType.primType
val dstType = primType
- val fromRestriction: Option[TypeCalculator] = optRestriction.flatMap({
restriction =>
- val enumerations =
restriction.enumerations.filter(_.optRepValueSet.isDefined)
- if (enumerations.isEmpty) {
- /*
- * In theory, we require srcType == dstType.
- * But, we also compute this when we are an expression calculator.
- * In such a case, the above invariant may not hold, which is okay,
because we
- * will not actually use the identity calculator.
- */
- Some(TypeCalculatorCompiler.compileIdentity(srcType))
+ val fromRestriction: Option[TypeCalculator] = optRestriction.flatMap {
restriction =>
+ if (restriction.enumerations.isEmpty) {
+ None
} else {
- if (enumerations.size != restriction.enumerations.size) {
- SDE("If one enumeration value defines a repValue, then all must
define a repValue")
+ val terms = restriction.enumerations.flatMap { enum =>
+ if (enum.optRepValueSet.isEmpty) {
+ None
+ } else {
+ Assert.invariant(enum.canonicalRepValue.isDefined)
+ val repValues = enum.optRepValueSet.get
+ val canonValues = enum.canonicalRepValue.getNonNullable
+ val cookedValue = enum.enumValueCooked
+ Some((repValues, canonValues, cookedValue))
+ }
+ }
+
+ if (terms.isEmpty) {
+ if (srcType != dstType) {
+ SDE(
+ """An enumeration without any dfdlx:repValues or
dfdlx:repValueRanges cannot have a different primitve type (%s) than that of
its dfdlx:repType="%s" (%s)""",
+ dstType.globalQName,
+ repType.namedQName,
+ srcType.globalQName,
+ )
+ }
+ Some(TypeCalculatorCompiler.compileIdentity(srcType))
+ } else {
+ if (terms.size != restriction.enumerations.size) {
+ SDE(
+ "If one enumeration value defines dfdlx:repValues, then all
must define a dfdlx:repValues",
+ )
+ }
+ Some(TypeCalculatorCompiler.compileKeysetValue(terms, srcType,
dstType))
}
- val terms = enumerations.map(enum => {
- Assert.invariant(enum.canonicalRepValue.isDefined)
- (
- enum.optRepValueSet.get,
- enum.canonicalRepValue.getNonNullable,
- enum.enumValueCooked,
- )
- })
- Some(TypeCalculatorCompiler.compileKeysetValue(terms, srcType,
dstType))
}
- })
- val fromUnion: Option[TypeCalculator] = optUnion.map({ union =>
+ }
+
+ val fromUnion: Option[TypeCalculator] = optUnion.map { union =>
val subCalculators: Seq[(RepValueSet, RepValueSet, TypeCalculator)] =
union.unionMemberTypes.map(subType =>
(
@@ -355,113 +374,22 @@ abstract class SimpleTypeDefBase(xml: Node,
lexicalParent: SchemaComponent)
),
)
TypeCalculatorCompiler.compileUnion(subCalculators)
- })
- val fromExpression: Option[TypeCalculator] = {
- /*
- * This is a minefield for circular dependencies.
- * In order to compile expressions involve many typeCalc functions,
- * the DPath compiler needs to look up the typeCalculator involved
- * (to determine the src/dst type of the calculator)
- * However, a fromExpression typeCalculator needs to compile DPath
expressions,
- * which may make use of typeCalc functions, and therefore need for
the expressions
- * to have been already compiled.
- */
- lazy val optInputCompiled = optInputTypeCalc.toOption.map(sExpr => {
- val prop = optInputTypeCalc.asInstanceOf[Found]
- val qn = GlobalQName(Some("dfdlx"), "inputTypeCalc",
XMLUtils.dafintURI)
- val exprNamespaces = prop.location.namespaces
- val exprComponent = prop.location.asInstanceOf[SchemaComponent]
- ExpressionCompilers.AnyRef.compileExpression(
- qn,
- dstType,
- sExpr,
- exprNamespaces,
- exprComponent.dpathCompileInfo,
- false,
- this,
- dpathCompileInfo,
- )
- })
- lazy val optOutputCompiled = optOutputTypeCalc.toOption.map(sExpr => {
- val prop = optOutputTypeCalc.asInstanceOf[Found]
- val qn = GlobalQName(Some("daf"), "outputTypeCalc",
XMLUtils.dafintURI)
- val exprNamespaces = prop.location.namespaces
- val exprComponent = prop.location.asInstanceOf[SchemaComponent]
- ExpressionCompilers.AnyRef.compileExpression(
- qn,
- srcType,
- sExpr,
- exprNamespaces,
- exprComponent.dpathCompileInfo,
- false,
- this,
- dpathCompileInfo,
- )
- })
- val supportsParse = optInputTypeCalc.isDefined
- val supportsUnparse = optOutputTypeCalc.isDefined
- val res = {
- if (supportsParse || supportsUnparse) {
- Some(
- TypeCalculatorCompiler.compileTypeCalculatorFromExpression(
- optInputCompiled,
- optOutputCompiled,
- srcType,
- dstType,
- ),
- )
- } else {
- None
- }
- }
- res
}
- val ans = (fromRestriction, fromUnion, fromExpression) match {
- case (Some(x), None, None) => Some(x)
- case (None, Some(x), None) => Some(x)
- case (None, None, Some(x)) =>
+ val ans = (fromRestriction, fromUnion) match {
+ case (Some(x), None) => Some(x)
+ case (None, Some(x)) => Some(x)
+ case (None, None) => {
SDE(
- "Usage of inputTypeCalc and outputTypeCalc requires an empty
xs:restriction to determine the base type.",
+ "dfdlx:repType (%s) requires an enumeration or union with defined
dfdlx:repValues",
+ repType.namedQName,
)
- case (Some(x), _, Some(y)) if x.isInstanceOf[IdentifyTypeCalculator]
=> Some(y)
- case (None, None, None) => {
- if (dstType != srcType) {
- val repTypeName = optRepTypeDef match {
- case Some(r) => r.diagnosticDebugName
- case None => repType.toString()
- }
- SDE(
- "repType (%s) with primitive type (%s) used without defining a
transformation is not compatable with the baseType of (%s) with primitive type
(%s)",
- repTypeName,
- srcType.name,
- diagnosticDebugName,
- dstType.name,
- )
- }
- None
}
- case (Some(_), Some(_), _) =>
+ case (Some(_), Some(_)) =>
Assert.invariantFailed("Cannot combine an enumeration with a union")
- case (Some(_), _, Some(_)) =>
- SDE("Cannot use typeCalcExpressions while defining repValues of
enumerations")
- case (_, Some(_), Some(_)) =>
- SDE("Cannot use typeCalcExpressions while using a union that defines
typeCalcs")
- }
-
- ans match {
- case Some(idt: IdentifyTypeCalculator) => {
- if (srcType != dstType) {
- SDE(
- "Identity transform requires that the basetype and reptype have
a common primitive type",
- )
- }
- }
- case _ => ()
}
ans
-
})
}.value
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesExpressions.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesExpressions.scala
index f6e0fbc86..72a7f1879 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesExpressions.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/PrimitivesExpressions.scala
@@ -343,9 +343,6 @@ case class TypeValueCalc(e: ElementBase) extends
Terminal(e, e.hasRepType) {
simpleTypeDefBase.optRepTypeElement.get.enclosedElement.unparser
override lazy val parser: DaffodilParser = {
- if (!typeCalculator.supportsParse) {
- SDE("Parsing not defined by typeValueCalc")
- }
new TypeValueCalcParser(
typeCalculator,
repTypeParser,
@@ -354,9 +351,6 @@ case class TypeValueCalc(e: ElementBase) extends
Terminal(e, e.hasRepType) {
)
}
override lazy val unparser: DaffodilUnparser = {
- if (!typeCalculator.supportsUnparse) {
- SDE("Unparsing not defined by typeValueCalc")
- }
new TypeValueCalcUnparser(
typeCalculator,
repTypeUnparser,
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
index ba7d0df96..9920d7d7c 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ElementBaseRuntime1Mixin.scala
@@ -155,7 +155,6 @@ trait ElementBaseRuntime1Mixin { self: ElementBase =>
optPrimType,
schemaFileLocation,
tunable.unqualifiedPathStepPolicy,
- schemaSet.typeCalcMap,
shortSchemaComponentDesignator,
isOutputValueCalc,
isDistinguishedRoot,
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SchemaSetRuntime1Mixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SchemaSetRuntime1Mixin.scala
index 2756d4f55..32eb6461d 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SchemaSetRuntime1Mixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SchemaSetRuntime1Mixin.scala
@@ -35,15 +35,6 @@ trait SchemaSetRuntime1Mixin {
requiredEvaluationsAlways(unparser)
requiredEvaluationsAlways(root.elementRuntimeData.initialize)
- /**
- * This initialization is required for simpleTypeDefs used only
- * for type calculations where those simpleTypeDefs do not have
- * a corresponding element of that type.
- */
- requiredEvaluationsAlways(typeCalcMap.foreach { case (_, typeCalculator) =>
- typeCalculator.initialize()
- })
-
override lazy val variableMap: VariableMap = LV('variableMap) {
val dvs = allSchemaDocuments.flatMap {
_.defineVariables
@@ -78,7 +69,7 @@ trait SchemaSetRuntime1Mixin {
val p = if (!root.isError) parser else null
val u = if (!root.isError) unparser else null
val ssrd =
- new SchemaSetRuntimeData(p, u, rootERD, variableMap, typeCalcMap)
+ new SchemaSetRuntimeData(p, u, rootERD, variableMap)
if (root.numComponents > root.numUniqueComponents)
Logger.log.debug(
s"Compiler: component counts: unique ${root.numUniqueComponents},
actual ${root.numComponents}.",
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
index 6a956de4f..9f870ffc8 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/SimpleTypeRuntime1Mixin.scala
@@ -22,13 +22,6 @@ import
org.apache.daffodil.runtime1.processors.SimpleTypeRuntimeData
trait SimpleTypeRuntime1Mixin { self: SimpleTypeDefBase =>
- /**
- * Initialize cyclic structure
- */
- requiredEvaluationsIfActivated(simpleTypeRuntimeData.typeCalculator.map { tc
=>
- tc.initialize
- })
-
lazy val simpleTypeRuntimeData: SimpleTypeRuntimeData = {
val strd =
new SimpleTypeRuntimeData(
@@ -55,7 +48,6 @@ trait SimpleTypeRuntime1Mixin { self: SimpleTypeDefBase =>
tunable.unqualifiedPathStepPolicy,
optRepTypeDef.map(_.simpleTypeRuntimeData),
optRepValueSet,
- optTypeCalculator,
optRepType.map(_.primType),
)
strd
diff --git
a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
index 395aed008..a5d38a383 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dfdlx.xsd
@@ -37,9 +37,7 @@
<xs:enumeration value="dfdlx:alignmentKind" />
<xs:enumeration value="dfdlx:choiceBranchKeyRanges" />
<xs:enumeration value="dfdlx:emptyElementParsePolicy"/> <!-- deprecated
-->
- <xs:enumeration value="dfdlx:inputTypeCalc"/>
<xs:enumeration value="dfdlx:objectKind"/>
- <xs:enumeration value="dfdlx:outputTypeCalc"/>
<xs:enumeration value="dfdlx:parseUnparsePolicy"/>
<xs:enumeration value="dfdlx:repType"/>
<xs:enumeration value="dfdlx:repValueRanges"/>
@@ -106,8 +104,6 @@
<xs:attributeGroup name="SimpleTypeValueCalcAG">
<xs:attribute form="qualified" name="repType" type="dfdl:DFDLQName" />
- <xs:attribute form="qualified" name="inputTypeCalc"
type="dfdl:DFDLExpression" />
- <xs:attribute form="qualified" name="outputTypeCalc"
type="dfdl:DFDLExpression" />
<xs:attributeGroup ref="dfdlx:RepValuesAG" />
</xs:attributeGroup>
@@ -118,8 +114,6 @@
<xs:attributeGroup name="SimpleTypeValueCalcAGQualified">
<xs:attribute form="qualified" name="repType" type="dfdl:DFDLQName" />
- <xs:attribute form="qualified" name="inputTypeCalc"
type="dfdl:DFDLExpression" />
- <xs:attribute form="qualified" name="outputTypeCalc"
type="dfdl:DFDLExpression" />
<xs:attributeGroup ref="dfdlx:RepValuesAGQualified" />
</xs:attributeGroup>
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXTypeCalcFunctions.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXTypeCalcFunctions.scala
deleted file mode 100644
index e37e13b16..000000000
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXTypeCalcFunctions.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.daffodil.runtime1.dpath
-
-import org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitive
-import org.apache.daffodil.runtime1.processors.TypeCalculator
-
-case class DFDLXInputTypeCalc(
- typedRecipes: List[(CompiledDPath, NodeInfo.Kind)],
- calc: TypeCalculator,
-) extends FNTwoArgs(typedRecipes.map(_._1)) {
-
- val srcType = typedRecipes(1)._2
-
- override def computeValue(
- arg1: DataValuePrimitive,
- arg2: DataValuePrimitive,
- dstate: DState,
- ): DataValuePrimitive = {
- calc.inputTypeCalcRun(dstate, arg2, srcType)
- dstate.currentValue.getNonNullable
- }
-
-}
-
-case class DFDLXOutputTypeCalc(
- typedRecipes: List[(CompiledDPath, NodeInfo.Kind)],
- calc: TypeCalculator,
-) extends FNTwoArgs(typedRecipes.map(_._1)) {
-
- val srcType = typedRecipes(1)._2
-
- def computeValue(
- arg1: DataValuePrimitive,
- arg2: DataValuePrimitive,
- dstate: DState,
- ): DataValuePrimitive = {
- calc.outputTypeCalcRun(dstate, arg2, srcType)
- dstate.currentValue.getNonNullable
- }
-}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DState.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DState.scala
index d8e6719fc..e5d4b13b0 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DState.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DState.scala
@@ -124,18 +124,6 @@ case class DState(
var opIndex: Int = 0
- /*
- * Used by TypeValueCalc to pass the logical or representation value to the
DPath runtime.
- * In principle, TypeValueCalc can be used recursively, so these data
structures are really a stack.
- * Instead of storing the stack explicitly, we rely on the runtime stack.
- * When ExpressionTypeCalculator begins a computation, it saves the previous
value of logical/repValue to a local variable
- * (eg. to the runtime stack), and replaces the below fields.
- * At the end of the computation, it should restore the below fields.
- */
- var logicalValue: DataValuePrimitiveNullable = DataValue.NoValue
-
- var repValue: DataValuePrimitiveNullable = DataValue.NoValue
-
/**
* The currentValue is used when we have a value that is not
* associated with an element of simple type. E.g., If I have
@@ -359,8 +347,6 @@ case class DState(
Nope
}
- def typeCalculators = maybeSsrd.get.typeCalculators
-
private var _savesErrorsAndWarnings: Maybe[SavesErrorsAndWarnings] = Nope
def errorOrWarn = _savesErrorsAndWarnings
def setErrorOrWarn(s: SavesErrorsAndWarnings): Unit = {
@@ -451,7 +437,6 @@ class DStateForConstantFolding(
override def selfMove() = die
override def fnExists() = die
override def arrayLength = die
- override val typeCalculators = compileInfo.typeCalcMap
isCompile = true
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/CompiledExpression1.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/CompiledExpression1.scala
index 261d72034..44c54a641 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/CompiledExpression1.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/CompiledExpression1.scala
@@ -38,7 +38,6 @@ import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
import org.apache.daffodil.runtime1.infoset.DataValue
import org.apache.daffodil.runtime1.processors.ParseOrUnparseState
import org.apache.daffodil.runtime1.processors.Suspension
-import
org.apache.daffodil.runtime1.processors.TypeCalculatorCompiler.TypeCalcMap
import org.apache.daffodil.runtime1.processors.VariableMap
trait ContentValueReferencedElementInfoMixin {
@@ -149,11 +148,6 @@ final case class ConstantExpression[+T <: AnyRef](qn:
NamedQName, kind: NodeInfo
override def evaluate(state: ParseOrUnparseState) = value
- def evaluate(dstate: DState, state: ParseOrUnparseState) = {
- dstate.setCurrentValue(DataValue.unsafeFromAnyRef(value))
- value
- }
-
override def run(dstate: DState) =
dstate.setCurrentValue(DataValue.unsafeFromAnyRef(value))
final def evaluateForwardReferencing(
@@ -218,7 +212,6 @@ class DPathCompileInfo(
val path: String,
override val schemaFileLocation: SchemaFileLocation,
val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
- typeCalcMapArg: TypeCalcMap,
) extends ImplementsThrowsSDE
with PreSerialization
with HasSchemaFileLocation {
@@ -268,11 +261,6 @@ class DPathCompileInfo(
parentsField.setAccessible(false)
}
- /*
- * This map(identity) pattern appears to work around an unidentified bug
with serialization.
- */
- lazy val typeCalcMap: TypeCalcMap = typeCalcMapArg.map(identity)
-
def diagnosticDebugName = path
@throws(classOf[java.io.IOException])
@@ -362,7 +350,6 @@ class DPathElementCompileInfo(
val optPrimType: Option[PrimType],
sfl: SchemaFileLocation,
override val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
- typeCalcMap: TypeCalcMap,
val sscd: String,
val isOutputValueCalc: Boolean,
val isDistinguishedRoot: Boolean,
@@ -373,7 +360,6 @@ class DPathElementCompileInfo(
path,
sfl,
unqualifiedPathStepPolicy,
- typeCalcMap,
) {
/**
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
index 30cd8ac71..f9fc172c6 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/RuntimeData.scala
@@ -223,7 +223,6 @@ final class SimpleTypeRuntimeData(
unqualifiedPathStepPolicyArg: UnqualifiedPathStepPolicy,
val repTypeRuntimeData: Option[SimpleTypeRuntimeData],
val repValueSet: Option[RepValueSet],
- val typeCalculator: Option[TypeCalculator],
val optRepPrimType: Option[PrimType],
) extends NonTermRuntimeData(
variableMapArg,
@@ -742,7 +741,6 @@ sealed abstract class ErrorERD(local: String, namespaceURI:
String)
None, // val optPrimType: Option[PrimType],
null, // sfl: SchemaFileLocation,
null, // override val unqualifiedPathStepPolicy :
UnqualifiedPathStepPolicy,
- null, // typeCalcMap: TypeCalcMap,
null, // val sscd: String),
false, // val isOutputValueCalc: Boolean
false, // val isDistinguishedRoot: Boolean
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/SchemaSetRuntimeData.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/SchemaSetRuntimeData.scala
index ac0b7e3f8..03d55809e 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/SchemaSetRuntimeData.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/SchemaSetRuntimeData.scala
@@ -18,7 +18,6 @@
package org.apache.daffodil.runtime1.processors
import org.apache.daffodil.lib.exceptions.ThrowsSDE
-import
org.apache.daffodil.runtime1.processors.TypeCalculatorCompiler.TypeCalcMap
import org.apache.daffodil.runtime1.processors.parsers.Parser
import org.apache.daffodil.runtime1.processors.unparsers.Unparser
@@ -30,7 +29,6 @@ final class SchemaSetRuntimeData(
* The original variables determined by the schema compiler.
*/
variables: VariableMap,
- val typeCalculators: TypeCalcMap,
) extends Serializable
with ThrowsSDE {
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/TypeCalculator.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/TypeCalculator.scala
index 64131d228..7d602d097 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/TypeCalculator.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/TypeCalculator.scala
@@ -21,14 +21,9 @@ import scala.collection.immutable.HashMap
import scala.collection.immutable.HashSet
import org.apache.daffodil.lib.exceptions.Assert
-import org.apache.daffodil.lib.util.Delay
import org.apache.daffodil.lib.util.Maybe
-import org.apache.daffodil.lib.util.Maybe.One
import org.apache.daffodil.lib.util.Numbers
-import org.apache.daffodil.lib.xml.QNameBase
-import org.apache.daffodil.runtime1.dpath.DState
import org.apache.daffodil.runtime1.dpath.NodeInfo
-import org.apache.daffodil.runtime1.dsom.CompiledExpression
import org.apache.daffodil.runtime1.infoset.DataValue
import org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitive
import
org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitiveNullable
@@ -36,120 +31,89 @@ import
org.apache.daffodil.runtime1.processors.parsers.PState
import org.apache.daffodil.runtime1.processors.parsers.ParseError
import org.apache.daffodil.runtime1.processors.unparsers.UState
+/**
+ * A TypeCalculator is a class that performs some kind of conversion from one
DataValuePrimitive
+ * to another DataValuePrimitive. In general, this is done to convert a parsed
physical
+ * representation from the data to a logical representation that goes in the
infoset, and
+ * reverse on unparse. The former is done in the inputTypeCalc functions, and
the latter in the
+ * outputTypeCalc functions. While these TypeCalculators are generic can in
theory support
+ * convertting between any types, their only use is converting from and int to
a string for
+ * parse, and the reverse for unparse.
+ *
+ * The different TypeCalculator implementations allow for different
conversions based on
+ * different properties provided in the schema (e.g. repType, enumerations,
unions, repValues,
+ * repValueRanges).
+ */
abstract class TypeCalculator(val srcType: NodeInfo.Kind, val dstType:
NodeInfo.Kind)
extends Serializable {
type Error = String
- def initialize(): Unit = {
- // base method does nothing
- }
-
- /*
- * We can be used from both a parser directly, and as part of a DPath
expression.
- * There are 2 main differences that require handling these cases seperatly
- *
- * 1) A (un)parser expects errors to be reported via state.setFailed, while
DPath expects subexpressions to report
- * error by throwing
- * 2) DPathCompiledExpressions provides a top level interface to initiate
evaluation which accepts a ParseOrUnparseState,
- * and a second interface to evaluate subexpressions which accepts a
DState
+ /**
+ * The inputTypeCalc function provides only the conversion logic, returning
either the new
+ * value or an error string. This allows it to be agnostic about how to
handle the resulting
+ * value or error, assuming the caller knows best. If a caller needs
normalization and
+ * errors to become ParseErrors, they should instead call inputTypeCalcParse.
*/
-
def inputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error])
+ ): Either[Error, DataValuePrimitiveNullable]
+
+ /**
+ * The outputTypeCalc function provides only the conversion logic, returning
either the new
+ * value or an error string. This allows it to be agnostic about how to
handle the resulting
+ * value or error, assuming the caller knows best. If a caller needs
normalization and
+ * errors to become UnparseErrors, they should instead call
outputTypeCalcUnparse.
+ */
def outputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error])
+ ): Either[Error, DataValuePrimitiveNullable]
- def inputTypeCalcParse(
+ final def inputTypeCalcParse(
pstate: PState,
context: RuntimeData,
x_in: DataValuePrimitive,
xType: NodeInfo.Kind,
): DataValuePrimitiveNullable = {
val x = normalizeArg(x_in, xType)
- val (ans, err) = inputTypeCalc(x, xType)
- Assert.invariant(ans.isDefined ^ err.isDefined)
-
- if (err.isDefined) {
- val diag = new ParseError(
- Maybe(context.schemaFileLocation),
- Maybe(pstate.currentLocation),
- err.get,
- )
- pstate.setFailed(diag)
+ val res = inputTypeCalc(x, xType) match {
+ case Left(err) => {
+ val diag = new ParseError(
+ Maybe(context.schemaFileLocation),
+ Maybe(pstate.currentLocation),
+ err,
+ )
+ pstate.setFailed(diag)
+ DataValue.NoValue
+ }
+ case Right(ans) => ans
}
-
- ans
+ res
}
- def outputTypeCalcUnparse(
+
+ final def outputTypeCalcUnparse(
ustate: UState,
context: RuntimeData,
x_in: DataValuePrimitive,
xType: NodeInfo.Kind,
): DataValuePrimitiveNullable = {
val x = normalizeArg(x_in, xType)
- val (ans, err) = outputTypeCalc(x, xType)
- Assert.invariant(ans.isDefined ^ err.isDefined)
-
- if (err.isDefined) {
- val diag = new ParseError(
- Maybe(context.schemaFileLocation),
- Maybe(ustate.currentLocation),
- err.get,
- )
- ustate.setFailed(diag)
- }
-
- // In event of an error, we still want to return Maybe.Nope, which happens
- // to be what ans would have
- ans
- }
-
- /*
- * It appears that dpath expressions actually throw errors.
- * See the definition of DAFError
- */
- def inputTypeCalcRun(dstate: DState, x_in: DataValuePrimitive, xType:
NodeInfo.Kind): Unit = {
- val x = normalizeArg(x_in, xType)
- val context = dstate.runtimeData.get
- val (ans, err) = inputTypeCalc(x, xType)
- Assert.invariant(ans.isDefined ^ err.isDefined)
-
- if (err.isDefined) {
- val diag =
- new ParseError(Maybe(context.schemaFileLocation),
dstate.contextLocation, err.get)
- throw diag
- }
-
- dstate.setCurrentValue(ans)
-
- }
- def outputTypeCalcRun(
- dstate: DState,
- x_in: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): Unit = {
- val x = normalizeArg(x_in, xType)
- val context = dstate.runtimeData.get
- val (ans, err) = outputTypeCalc(x, xType)
- Assert.invariant(ans.isDefined ^ err.isDefined)
-
- if (err.isDefined) {
- val diag =
- new ParseError(Maybe(context.schemaFileLocation),
dstate.contextLocation, err.get)
- throw diag
+ val res = outputTypeCalc(x, xType) match {
+ case Left(err) => {
+ val diag = new ParseError(
+ Maybe(context.schemaFileLocation),
+ Maybe(ustate.currentLocation),
+ err,
+ )
+ ustate.setFailed(diag)
+ DataValue.NoValue
+ }
+ case Right(ans) => ans
}
-
- dstate.setCurrentValue(ans)
-
+ res
}
- def supportsParse: Boolean = true
- def supportsUnparse: Boolean = true
-
/*
* In theory, this normalizeArg method should not be nessasary. We know at
compile time what
* types a given calculator is defined in terms of, so the compiler should
insert any conversion
@@ -183,9 +147,9 @@ class KeysetValueTypeCalculatorOrdered(
override def inputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
+ ): Either[Error, DataValuePrimitiveNullable] = {
if (valueMap.contains(x)) {
- (valueMap.get(x).get, Maybe.Nope)
+ Right(valueMap.get(x).get)
} else {
val ans1: Option[(RangeBound, RangeBound, DataValuePrimitiveNullable)] =
rangeTable.find({
case (min, max, _) => {
@@ -194,9 +158,9 @@ class KeysetValueTypeCalculatorOrdered(
})
ans1 match {
case None => {
- (DataValue.NoValue, One(s"Value ${x} not found in enumeration
dfdlx:repValues"))
+ Left(s"Value ${x} not found in enumeration dfdlx:repValues")
}
- case Some((_, _, v)) => (v, Maybe.Nope)
+ case Some((_, _, v)) => Right(v)
}
}
}
@@ -204,10 +168,10 @@ class KeysetValueTypeCalculatorOrdered(
override def outputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
+ ): Either[Error, DataValuePrimitiveNullable] = {
unparseMap.get(x) match {
- case Some(v) => (v, Maybe.Nope)
- case None => (DataValue.NoValue, One(s"Value ${x} not found in
enumeration"))
+ case Some(v) => Right(v)
+ case None => Left(s"Value ${x} not found in enumeration")
}
}
@@ -223,159 +187,34 @@ class KeysetValueTypeCalculatorUnordered(
override def inputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
+ ): Either[Error, DataValuePrimitiveNullable] = {
valueMap.get(x) match {
- case Some(a) => (a, Maybe.Nope)
- case None =>
- (DataValue.NoValue, One(s"Value ${x} not found in enumeration
dfdlx:repValues"))
+ case Some(a) => Right(a)
+ case None => Left(s"Value ${x} not found in enumeration dfdlx:repValues")
}
}
override def outputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
+ ): Either[Error, DataValuePrimitiveNullable] = {
unparseMap.get(x) match {
- case Some(v) => (v, Maybe.Nope)
- case None => (DataValue.NoValue, One(s"Value ${x} not found in
enumeration"))
+ case Some(v) => Right(v)
+ case None => Left(s"Value ${x} not found in enumeration")
}
}
}
-class ExpressionTypeCalculator(
- private val maybeInputTypeCalcDelay:
Delay[Maybe[CompiledExpression[AnyRef]]],
- private val maybeOutputTypeCalcDelay:
Delay[Maybe[CompiledExpression[AnyRef]]],
- srcType: NodeInfo.Kind,
- dstType: NodeInfo.Kind,
-) extends TypeCalculator(srcType, dstType) {
-
- /*
- * objects with Delay arguments for functional programming construction of
- * cyclic graphs, need a way to force the delays, resulting in an ordinary
- * (though cyclic) data structure.
- */
- final override def initialize(): Unit = {
- super.initialize()
- maybeInputTypeCalc
- maybeOutputTypeCalc
- }
-
- override def supportsParse = maybeInputTypeCalc.isDefined
- override def supportsUnparse = maybeOutputTypeCalc.isDefined
-
- /*
- * Compiling DPath expressions may need to evaluate typeCalculators in order
to lookup their srcType and dstType.
- * To prevent circular dependencies, this means that the underlying
expressions must be lazy.
- *
- * Since these fields must be lazy, we cannot use them to determine
supportsParse or supportUnparse
- */
- lazy val maybeInputTypeCalc = maybeInputTypeCalcDelay.value
- lazy val maybeOutputTypeCalc = maybeOutputTypeCalcDelay.value
-
- // The class TypeValueCalc will verify that supports(Un)Parse is true when
nessasary
- // Therefore, if we ever call the below functions, we know that the relevent
Maybe object is defined.
-
- // TODO, pass x into DPath state
-
+class IdentityTypeCalculator(srcType: NodeInfo.Kind) extends
TypeCalculator(srcType, srcType) {
override def inputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) =
- Assert.invariantFailed(
- "inputTypeCalc not implemented on ExpressionTypeCalculator. Call the
more specialized forms directly",
- )
+ ): Either[Error, DataValuePrimitiveNullable] = Right(x)
override def outputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) =
- Assert.invariantFailed(
- "outputTypeCalc not implemented on ExpressionTypeCalculator. Call the
more specialized forms directly",
- )
-
- override def inputTypeCalcParse(
- state: PState,
- context: RuntimeData,
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): DataValuePrimitiveNullable = {
- val dstate = state.dState
- val oldRepValue = dstate.repValue
- val oldLogicalValue = dstate.logicalValue
- dstate.repValue = x
- dstate.logicalValue = DataValue.NoValue
-
- val ans = Maybe(maybeInputTypeCalc.get.evaluate(state))
-
- dstate.repValue = oldRepValue
- dstate.logicalValue = oldLogicalValue
- if (ans.isDefined) {
- DataValue.unsafeFromAnyRef(ans.get)
- } else {
- DataValue.NoValue;
- }
- }
- override def outputTypeCalcUnparse(
- state: UState,
- context: RuntimeData,
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): DataValuePrimitiveNullable = {
- val dstate = state.dState
- val oldRepValue = dstate.repValue
- val oldLogicalValue = dstate.logicalValue
- dstate.repValue = DataValue.NoValue
- dstate.logicalValue = x
-
- val ans = maybeOutputTypeCalc.get.evaluate(state)
-
- dstate.repValue = oldRepValue
- dstate.logicalValue = oldLogicalValue
- DataValue.unsafeFromAnyRef(ans)
- }
-
- override def inputTypeCalcRun(
- dstate: DState,
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): Unit = {
- val oldRepValue = dstate.repValue
- val oldLogicalValue = dstate.logicalValue
- dstate.repValue = x
- dstate.logicalValue = DataValue.NoValue
-
- maybeInputTypeCalc.get.run(dstate)
-
- dstate.repValue = oldRepValue
- dstate.logicalValue = oldLogicalValue
-
- }
- override def outputTypeCalcRun(
- dstate: DState,
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): Unit = {
- val oldRepValue = dstate.repValue
- val oldLogicalValue = dstate.logicalValue
- dstate.repValue = DataValue.NoValue
- dstate.logicalValue = x
-
- maybeOutputTypeCalc.get.run(dstate)
-
- dstate.repValue = oldRepValue
- dstate.logicalValue = oldLogicalValue
- }
-}
-
-class IdentifyTypeCalculator(srcType: NodeInfo.Kind) extends
TypeCalculator(srcType, srcType) {
- override def inputTypeCalc(
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = (x, Maybe.Nope)
- override def outputTypeCalc(
- x: DataValuePrimitive,
- xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = (x, Maybe.Nope)
+ ): Either[Error, DataValuePrimitiveNullable] = Right(x)
}
class UnionTypeCalculator(
@@ -388,14 +227,11 @@ class UnionTypeCalculator(
override def inputTypeCalc(
x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
+ ): Either[Error, DataValuePrimitiveNullable] = {
val subCalcSeq = subCalculators.filter(sub => sub._1.contains(x))
Assert.invariant(subCalcSeq.length <= 1)
if (subCalcSeq.isEmpty) {
- (
- DataValue.NoValue,
- One(s"Key ${x} does not match any component of this simpleType union"),
- )
+ Left(s"Key ${x} does not match any component of this simpleType union")
} else {
val subCalc = subCalcSeq.head._3
subCalc.inputTypeCalc(x, xType)
@@ -403,17 +239,13 @@ class UnionTypeCalculator(
}
override def outputTypeCalc(
- x_in: DataValuePrimitive,
+ x: DataValuePrimitive,
xType: NodeInfo.Kind,
- ): (DataValuePrimitiveNullable, Maybe[Error]) = {
- val x = normalizeArg(x_in, xType)
+ ): Either[Error, DataValuePrimitiveNullable] = {
val subCalcSeq = subCalculators.filter(sub => sub._2.contains(x))
Assert.invariant(subCalcSeq.length <= 1)
if (subCalcSeq.isEmpty) {
- (
- DataValue.NoValue,
- One(s"Key ${x} does not match the logical values from any component of
this union."),
- )
+ Left(s"Key ${x} does not match the logical values from any component of
this union.")
} else {
val subCalc = subCalcSeq.head._3
subCalc.outputTypeCalc(x, xType)
@@ -470,8 +302,6 @@ object RepValueSetCompiler {
object TypeCalculatorCompiler {
- type TypeCalcMap = Map[QNameBase, TypeCalculator]
-
// mappings: [(keySet, canonicalKey, value)]
def compileKeysetValue(
mappings: Seq[(RepValueSet, DataValuePrimitive, DataValuePrimitive)],
@@ -513,31 +343,7 @@ object TypeCalculatorCompiler {
}
}
- /*
- * compileExpression is already a highly overloaded name from the DPath
expression compiler.
- * While this technically overload that function, to avoid confusion, we are
giving it a different
- * name entirely.
- */
- def compileTypeCalculatorFromExpression(
- optInputTypeCalc: => Option[CompiledExpression[AnyRef]],
- optOutputTypeCalc: => Option[CompiledExpression[AnyRef]],
- srcType: NodeInfo.Kind,
- dstType: NodeInfo.Kind,
- ): ExpressionTypeCalculator = {
- lazy val maybeInputType: Maybe[CompiledExpression[AnyRef]] =
- optInputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
- lazy val maybeOutputType: Maybe[CompiledExpression[AnyRef]] =
- optOutputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
- val tc =
- new ExpressionTypeCalculator(
- Delay('maybeInputType, this, maybeInputType),
- Delay('maybeOutputType, this, maybeOutputType),
- srcType,
- dstType,
- )
- tc
- }
- def compileIdentity(srcType: NodeInfo.Kind): TypeCalculator = new
IdentifyTypeCalculator(
+ def compileIdentity(srcType: NodeInfo.Kind): TypeCalculator = new
IdentityTypeCalculator(
srcType,
)
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ExpressionEvaluatingParsers.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ExpressionEvaluatingParsers.scala
index fa35fa4b1..214ae5f97 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ExpressionEvaluatingParsers.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/ExpressionEvaluatingParsers.scala
@@ -148,7 +148,6 @@ class TypeValueCalcParser(
val repValue: DataValuePrimitiveNullable =
runDetachedParser(pstate, repTypeParser, repTypeRuntimeData)
val repValueType = repTypeRuntimeData.optPrimType.get
- pstate.dataProc.get.ssrd
if (pstate.processorStatus == Success) {
Assert.invariant(repValue.isDefined)
val logicalValue: DataValuePrimitiveNullable =
typeCalculator.inputTypeCalcParse(
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enumInvalid.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enumInvalid.tdml
index c4226f1b8..6bc628d12 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enumInvalid.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enumInvalid.tdml
@@ -66,4 +66,50 @@
</errors>
</parserTestCase>
+ <tdml:defineSchema
+ name="s1"
+ useDefaultNamespace="false"
+ elementFormDefault="unqualified"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+
+ <include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+ <element name="r1">
+ <complexType>
+ <sequence>
+ <element name="e1" type="ex:enum1" minOccurs="0"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <simpleType name="myByte" dfdl:lengthKind="explicit" dfdl:length="1">
+ <restriction base="xs:byte"/>
+ </simpleType>
+
+ <simpleType name="enum1" dfdlx:repType="ex:myByte">
+ <restriction base="xs:string">
+ <enumeration value="validA" />
+ <enumeration value="validB" />
+ <enumeration value="invalidC" />
+ </restriction>
+ </simpleType>
+
+ </tdml:defineSchema>
+
+ <parserTestCase name="noRepValuesDifferentTypes" model="s1" root="r1">
+ <document>
+ <documentPart type="byte">01</documentPart>
+ </document>
+ <errors>
+ <error>Schema Definition Error</error>
+ <error>enumeration</error>
+ <error>dfdlx:repValues</error>
+ <error>different primitve type</error>
+ <error>xs:string</error>
+ <error>tns:myByte</error>
+ <error>xs:byte</error>
+ </errors>
+ </parserTestCase>
+
</testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
index 7923ae7c4..482e302a1 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/enum/enums.tdml
@@ -166,4 +166,45 @@
</infoset>
</parserTestCase>
+ <tdml:defineSchema
+ name="s3"
+ useDefaultNamespace="false"
+ elementFormDefault="unqualified"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+
+ <include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" representation="binary"/>
+
+ <element name="r1">
+ <complexType>
+ <sequence>
+ <element name="e1" type="ex:enum1" minOccurs="0"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <simpleType name="myString" dfdl:lengthKind="explicit" dfdl:length="6">
+ <restriction base="xs:string"/>
+ </simpleType>
+
+ <simpleType name="enum1" dfdlx:repType="ex:myString">
+ <restriction base="xs:string">
+ <enumeration value="validA" />
+ <enumeration value="validB" />
+ <enumeration value="validC" />
+ </restriction>
+ </simpleType>
+ </tdml:defineSchema>
+
+ <parserTestCase name="enumNoRepValues" model="s3" root="r1">
+ <document>validB</document>
+ <infoset>
+ <tdml:dfdlInfoset xmlns="">
+ <ex:r1>
+ <e1>validB</e1>
+ </ex:r1>
+ </tdml:dfdlInfoset>
+ </infoset>
+ </parserTestCase>
+
</testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalcExpression.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalcExpression.tdml
deleted file mode 100644
index 876555553..000000000
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalcExpression.tdml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<tdml:testSuite xmlns:ex="http://example.com" xmlns="http://example.com"
- xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions"
- xmlns:fn="http://www.w3.org/2005/xpath-functions"
- xmlns:tns="http://example.com"
- >
-
- <tdml:defineSchema name="inputTypeCalc-Embedded.dfdl.xsd">
-
- <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
- <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited"
- lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
- terminator="" occursCountKind="parsed" ignoreCase="no"
- textNumberRep="standard" representation="binary" />
-
- <xs:simpleType name="uint8" dfdl:lengthKind="explicit" dfdl:length="1">
- <xs:restriction base="xs:unsignedInt"/>
- </xs:simpleType>
-
-
- <xs:element name="inputTypeCalc_expression_01"
dfdlx:parseUnparsePolicy="parseOnly">
- <xs:simpleType dfdlx:inputTypeCalc="{ 7 }" dfdlx:repType="tns:uint8">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- </xs:element>
-
- <xs:element name="outputTypeCalc_expression_01"
dfdlx:parseUnparsePolicy="unparseOnly">
- <xs:simpleType dfdlx:outputTypeCalc="{ 7 }" dfdlx:repType="tns:uint8">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- </xs:element>
-
- <xs:element name="inputTypeCalc_expression_02">
- <xs:simpleType dfdlx:inputTypeCalc="{ 7 }" dfdlx:repType="tns:uint8">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- </xs:element>
-
- <xs:element name="outputTypeCalc_expression_02">
- <xs:simpleType dfdlx:outputTypeCalc="{ 7 }" dfdlx:repType="tns:uint8">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- </xs:element>
-
- </tdml:defineSchema>
-
- <tdml:parserTestCase name="InputTypeCalc_expression_01"
- root="inputTypeCalc_expression_01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- 01
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <inputTypeCalc_expression_01>7</inputTypeCalc_expression_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
- <tdml:unparserTestCase name="OutputTypeCalc_expression_01"
- root="outputTypeCalc_expression_01"
model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc
keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- 07
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <outputTypeCalc_expression_01>1</outputTypeCalc_expression_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:unparserTestCase>
-
- <tdml:parserTestCase name="InputTypeCalc_expression_02"
- root="outputTypeCalc_expression_02"
model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc
keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- 01
- </tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
- <tdml:unparserTestCase name="OutputTypeCalc_expression_02"
- root="inputTypeCalc_expression_02" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- </tdml:errors>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <inputTypeCalc_expression_02>1</inputTypeCalc_expression_02>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:unparserTestCase>
-
-</tdml:testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
deleted file mode 100644
index 387328adc..000000000
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<tdml:testSuite xmlns:ex="http://example.com" xmlns="http://example.com"
- xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions"
- xmlns:fn="http://www.w3.org/2005/xpath-functions"
- xmlns:tns="http://example.com"
- >
-
- <tdml:defineSchema name="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd">
-
- <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
- <dfdl:format ref="ex:GeneralFormat" lengthKind="implicit"
- lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
- terminator="" occursCountKind="parsed" ignoreCase="no"
- textNumberRep="standard" representation="binary"
- dfdlx:parseUnparsePolicy="parseOnly"
- />
-
- <xs:simpleType name="intToString" dfdlx:repType="xs:int"
dfdlx:inputTypeCalc="{ 'a' }" dfdlx:outputTypeCalc="{ 0 }">
- <xs:restriction base="xs:string"/>
- </xs:simpleType>
-
- <xs:simpleType name="stringToInt" dfdlx:repType="xs:string"
dfdlx:inputTypeCalc="{ 0 }" dfdlx:outputTypeCalc="{ 'a' }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:simpleType name="uint8" dfdl:length="1" dfdl:lengthKind="explicit">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:simpleType name="string8" dfdl:length="1" dfdl:lengthKind="explicit">
- <xs:restriction base="xs:string"/>
- </xs:simpleType>
-
- <xs:element name="typeCalcDispatch_typeError_01" type="xs:int"
dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:intToString', 0) }" />
- <xs:element name="typeCalcDispatch_typeError_02" type="xs:int"
dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:stringToInt', 0) }" />
-
- <xs:element name="nonexistant_reptype_01">
- <xs:simpleType dfdlx:repType="tns:nonExistant" dfdlx:inputTypeCalc="{ 0
}">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- </xs:element>
-
- <xs:simpleType name="inputConversionOnly" dfdlx:repType="tns:uint8"
dfdlx:inputTypeCalc="{ 1 }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:element name="nonexistantOutputTypeCalc_01" type="xs:int"
dfdl:inputValueCalc="{dfdlx:outputTypeCalc('tns:inputConversionOnly', 7)}"/>
-
- <xs:simpleType name="outputConversionOnly" dfdlx:repType="tns:uint8"
dfdlx:outputTypeCalc="{ 1 }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:element name="nonexistantInputTypeCalc_01" type="xs:int"
dfdl:inputValueCalc="{dfdlx:inputTypeCalc('tns:outputConversionOnly', 7)}"/>
-
- </tdml:defineSchema>
-
- <tdml:parserTestCase name="nonexistant_reptype_01"
- root="nonexistant_reptype_01"
model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions -
inputTypeCalc errors">
- <tdml:document>
- <tdml:documentPart type="byte"></tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>Cannot find reptype tns:nonExistant</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
- <tdml:parserTestCase name="nonexistantOutputTypeCalc_01"
- root="nonexistantOutputTypeCalc_01"
model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions -
inputTypeCalc errors">
- <tdml:document>
- <tdml:documentPart type="byte"></tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>tns:inputConversionOnly does not define an
outputValueCalc</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
- <tdml:parserTestCase name="nonexistantInputTypeCalc_01"
- root="nonexistantInputTypeCalc_01"
model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions -
inputTypeCalc errors">
- <tdml:document>
- <tdml:documentPart type="byte"></tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>tns:outputConversionOnly does not define an
inputValueCalc</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
- <tdml:defineSchema name="nonexistantTypeCalcType_01.dfdl.xsd">
- <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
- <dfdl:format ref="ex:GeneralFormat" lengthKind="implicit"
- lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
- terminator="" occursCountKind="parsed" ignoreCase="no"
- textNumberRep="standard" representation="binary"
- dfdlx:parseUnparsePolicy="parseOnly"
- />
-
- <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{
dfdlx:inputTypeCalc('tns:nonExistant', 0) }"/>
-
- </tdml:defineSchema>
-
- <tdml:parserTestCase name="nonexistantTypeCalcType_01"
- root="root" model="nonexistantTypeCalcType_01.dfdl.xsd"
description="Extensions - inputTypeCalc errors">
- <tdml:document>
- <tdml:documentPart type="byte"></tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>tns:nonExistant</tdml:error>
- <tdml:error>does not exist</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
- <tdml:defineSchema name="nonexistantTypeCalcType_02.dfdl.xsd">
- <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
- <dfdl:format ref="ex:GeneralFormat" lengthKind="implicit"
- lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
- terminator="" occursCountKind="parsed" ignoreCase="no"
- textNumberRep="standard" representation="binary"
- dfdlx:parseUnparsePolicy="parseOnly"
- />
-
- <xs:simpleType name="nonExistantTypeCalc">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
- <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{
dfdlx:inputTypeCalc('tns:nonExistantTypeCalc', 0) }"/>
-
- </tdml:defineSchema>
-
- <tdml:parserTestCase name="nonexistantTypeCalcType_02"
- root="root" model="nonexistantTypeCalcType_02.dfdl.xsd"
description="Extensions - inputTypeCalc errors">
- <tdml:document>
- <tdml:documentPart type="byte"></tdml:documentPart>
- </tdml:document>
- <tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>tns:nonExistant</tdml:error>
- <tdml:error>does not have a repType</tdml:error>
- </tdml:errors>
- </tdml:parserTestCase>
-
-</tdml:testSuite>
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
deleted file mode 100644
index 47cbd45e3..000000000
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
+++ /dev/null
@@ -1,263 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
--->
-
-<tdml:testSuite xmlns:ex="http://example.com" xmlns="http://example.com"
- xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions"
- xmlns:fn="http://www.w3.org/2005/xpath-functions"
- xmlns:tns="http://example.com">
-
- <tdml:defineSchema name="inputTypeCalc-Embedded.dfdl.xsd">
-
- <xs:include
schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
- <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited"
- lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
- terminator="" occursCountKind="parsed" ignoreCase="no"
- textNumberRep="standard" representation="binary" />
-
- <xs:simpleType name="uint8" dfdl:lengthKind="explicit" dfdl:length="1">
- <xs:restriction base="xs:unsignedInt"/>
- </xs:simpleType>
-
- <xs:simpleType name="AbstractIntTo1" dfdlx:repType="xs:int"
dfdlx:inputTypeCalc="{ 1 }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:simpleType name="AbstractIntToXYZ" dfdlx:repType="xs:int"
dfdlx:inputTypeCalc="{ 'xyz' }">
- <xs:restriction base="xs:string"/>
- </xs:simpleType>
-
- <xs:simpleType name="Abstract1FromInt" dfdlx:repType="xs:int"
dfdlx:outputTypeCalc="{ 1 }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:simpleType name="AbstractXYZFromInt" dfdlx:repType="xs:string"
dfdlx:outputTypeCalc="{ 'xyz' }">
- <xs:restriction base="xs:int"/>
- </xs:simpleType>
-
- <xs:simpleType name="AbstractIntToStringByKeyset" dfdlx:repType="xs:int">
- <xs:restriction base="xs:string">
- <xs:enumeration value="one" dfdlx:repValues="1"/>
- <xs:enumeration value="zero" dfdlx:repValues="0"/>
- </xs:restriction>
- </xs:simpleType>
-
- <xs:element name="inputTypeCalcInt_01" type="xs:int" dfdl:inputValueCalc="{
dfdlx:inputTypeCalc('tns:AbstractIntTo1', 7) }" />
- <xs:element name="inputTypeCalcString_01" type="xs:string"
dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:AbstractIntToXYZ', 7) }" />
-
- <xs:element name="outputTypeCalcInt_01"
dfdlx:parseUnparsePolicy="unparseOnly">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="inner" type="tns:uint8" dfdl:outputValueCalc="{
dfdlx:outputTypeCalc('tns:Abstract1FromInt', 7) }" />
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="outputTypeCalcString_01" type="xs:string"
dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:AbstractXYZFromInt', 7) }" />
-
- <xs:element name="abstractIntToStringByKeyset_01" type="xs:string"
dfdl:inputValueCalc="{dfdlx:inputTypeCalc('AbstractIntToStringByKeyset',0)}"/>
-
- <xs:element name="sparse_enum01">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="byte" maxOccurs="unbounded"
dfdl:occursCountKind="parsed">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="raw" type="tns:uint8"/>
- <xs:choice dfdl:choiceDispatchKey="{ xs:string(ex:raw) }">
- <xs:sequence dfdl:choiceBranchKey="15"
dfdlx:choiceBranchKeyRanges="1 3">
- <xs:element name="enum" type="tns:sparse_lookup"
dfdl:inputValueCalc="{ (dfdlx:inputTypeCalc('tns:sparse_lookup', (../ex:raw)))
}"/>
- </xs:sequence>
- <xs:sequence dfdl:choiceBranchKey="0"
dfdlx:choiceBranchKeyRanges="4 14 16 255">
- <xs:element name="undefined" type="xs:int"
dfdl:inputValueCalc="{ ../ex:raw }"/>
- </xs:sequence>
- </xs:choice>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-
- <xs:simpleType name="sparse_lookup" dfdlx:repType="xs:integer">
- <xs:restriction base="xs:string">
- <xs:enumeration value="one" dfdlx:repValues="1"/>
- <xs:enumeration value="two" dfdlx:repValues="2"/>
- <xs:enumeration value="three" dfdlx:repValues="3"/>
- <xs:enumeration value="fifteen" dfdlx:repValues="15"/>
- </xs:restriction>
- </xs:simpleType>
-
-
- </tdml:defineSchema>
-
- <tdml:parserTestCase name="inputTypeCalcInt_01"
- root="inputTypeCalcInt_01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <inputTypeCalcInt_01>1</inputTypeCalcInt_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
- <tdml:parserTestCase name="inputTypeCalcString_01"
- root="inputTypeCalcString_01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <inputTypeCalcString_01>xyz</inputTypeCalcString_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
- <tdml:unparserTestCase name="outputTypeCalcInt_01"
- root="outputTypeCalcInt_01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- 01
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <outputTypeCalcInt_01><inner>hello</inner></outputTypeCalcInt_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:unparserTestCase>
-
- <tdml:parserTestCase name="outputTypeCalcString_01"
- root="outputTypeCalcString_01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <outputTypeCalcString_01>xyz</outputTypeCalcString_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
- <tdml:parserTestCase name="abstractIntToStringByKeyset_01"
- root="abstractIntToStringByKeyset_01"
model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc
keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte">
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <abstractIntToStringByKeyset_01>zero</abstractIntToStringByKeyset_01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
- <tdml:parserTestCase name="sparse_enum_01"
- root="sparse_enum01" model="inputTypeCalc-Embedded.dfdl.xsd"
description="Extensions - inputTypeCalc keysetValue transform">
-
- <tdml:document>
- <tdml:documentPart type="byte"><![CDATA[
- 00
- 01
- 02
- 03
- 04
- 05
- 0d
- 0e
- 0f
- 10
- fe
- ff
- ]]>
- </tdml:documentPart>
- </tdml:document>
- <tdml:infoset>
- <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <sparse_enum01>
- <byte>
- <raw>0</raw>
- <undefined>0</undefined>
- </byte>
- <byte>
- <raw>1</raw>
- <enum>one</enum>
- </byte>
- <byte>
- <raw>2</raw>
- <enum>two</enum>
- </byte>
- <byte>
- <raw>3</raw>
- <enum>three</enum>
- </byte>
- <byte>
- <raw>4</raw>
- <undefined>4</undefined>
- </byte>
- <byte>
- <raw>5</raw>
- <undefined>5</undefined>
- </byte>
- <byte>
- <raw>13</raw>
- <undefined>13</undefined>
- </byte>
- <byte>
- <raw>14</raw>
- <undefined>14</undefined>
- </byte>
- <byte>
- <raw>15</raw>
- <enum>fifteen</enum>
- </byte>
- <byte>
- <raw>16</raw>
- <undefined>16</undefined>
- </byte>
- <byte>
- <raw>254</raw>
- <undefined>254</undefined>
- </byte>
- <byte>
- <raw>255</raw>
- <undefined>255</undefined>
- </byte>
- </sparse_enum01>
- </tdml:dfdlInfoset>
- </tdml:infoset>
- </tdml:parserTestCase>
-
-
-</tdml:testSuite>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestEnums.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestEnums.scala
index 5980f3c02..02a0a74aa 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestEnums.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestEnums.scala
@@ -39,8 +39,13 @@ class TestEnums {
@Test def test_enumValid1(): Unit = { runner.runOneTest("enumValid1") }
@Test def test_enumInvalid1(): Unit = { runner.runOneTest("enumInvalid1") }
@Test def test_enumMiss1(): Unit = { runner.runOneTest("enumMiss1") }
+ @Test def test_enumNoRepValues(): Unit = {
runner.runOneTest("enumNoRepValues") }
@Test def test_repTypeAlignment(): Unit = {
runner.runOneTest("repTypeAlignment") }
@Test def test_emptyRepValues(): Unit = {
runner2.runOneTest("emptyRepValues") }
+ @Test def test_noRepValuesDifferentTypes(): Unit = {
+ runner2.runOneTest("noRepValuesDifferentTypes")
+ }
+
}
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
index a7d7f014d..ab9eb19bf 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
@@ -26,15 +26,9 @@ object TestInputTypeValueCalc {
val testDir = "/org/apache/daffodil/extensions/type_calc/"
val runner = Runner(testDir, "inputTypeCalc.tdml", validateTDMLFile = false)
- val exprRunner = Runner(testDir, "inputTypeCalcExpression.tdml",
validateTDMLFile = false)
- val fnRunner = Runner(testDir, "typeCalcFunctions.tdml", validateTDMLFile =
false)
- val fnErrRunner = Runner(testDir, "typeCalcFunctionErrors.tdml",
validateTDMLFile = false)
@AfterClass def shutDown(): Unit = {
runner.reset
- exprRunner.reset
- fnRunner.reset
- fnErrRunner.reset
}
}
@@ -78,48 +72,4 @@ class TestInputTypeValueCalc {
@Test def test_unparseValueNotFound_2(): Unit = {
runner.runOneTest("unparseValueNotFound_2")
}
-
- @Test def test_InputTypeCalc_expression_01(): Unit = {
- exprRunner.runOneTest("InputTypeCalc_expression_01")
- }
- @Test def test_OutputTypeCalc_expression_01(): Unit = {
- exprRunner.runOneTest("OutputTypeCalc_expression_01")
- }
- @Test def test_InputTypeCalc_expression_02(): Unit = {
- exprRunner.runOneTest("InputTypeCalc_expression_02")
- }
- @Test def test_OutputTypeCalc_expression_02(): Unit = {
- exprRunner.runOneTest("OutputTypeCalc_expression_02")
- }
-
- @Test def test_inputTypeCalcInt_01(): Unit = {
fnRunner.runOneTest("inputTypeCalcInt_01") }
- @Test def test_inputTypeCalcString_01(): Unit = {
- fnRunner.runOneTest("inputTypeCalcString_01")
- }
- @Test def test_outputTypeCalcInt_01(): Unit = {
fnRunner.runOneTest("outputTypeCalcInt_01") }
- @Test def test_outputTypeCalcString_01(): Unit = {
- fnRunner.runOneTest("outputTypeCalcString_01")
- }
-
- @Test def test_abstractIntToStringByKeyset_01(): Unit = {
- fnRunner.runOneTest("abstractIntToStringByKeyset_01")
- }
- @Test def test_sparse_enum_01(): Unit = {
fnRunner.runOneTest("sparse_enum_01") }
-
- @Test def test_nonexistant_reptype_01(): Unit = {
- fnErrRunner.runOneTest("nonexistant_reptype_01")
- }
- @Test def test_nonexistantOutputTypeCalc_01(): Unit = {
- fnErrRunner.runOneTest("nonexistantOutputTypeCalc_01")
- }
- @Test def test_nonexistantInputTypeCalc_01(): Unit = {
- fnErrRunner.runOneTest("nonexistantInputTypeCalc_01")
- }
- @Test def test_nonexistantTypeCalcType_01(): Unit = {
- fnErrRunner.runOneTest("nonexistantTypeCalcType_01")
- }
- @Test def test_nonexistantTypeCalcType_02(): Unit = {
- fnErrRunner.runOneTest("nonexistantTypeCalcType_02")
- }
-
}