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 19eb2a371 Require that dfdlx:repType references a global simple type
definition
19eb2a371 is described below
commit 19eb2a371fdeeece8afa2c53d103d474cbbe30da
Author: Steve Lawrence <[email protected]>
AuthorDate: Tue Aug 29 11:20:45 2023 -0400
Require that dfdlx:repType references a global simple type definition
Primitive types do not carry any DFDL properties and so do not make for
very good repTypes. To support primitive types as a repType, all DFDL
proprties would need to come from the general format, which would only
make sense if a few specific cases.
Instead, we simply disallow primitive repTypes, instead requiring
that repType be a QName to a simple global type definition, which DFDL
properties can be put.
This creates a new function to create a helpful diagnostic when it is
detected that a repType references a primitive type. Additionally,
dfdl:prefixLengthType already has this restriction, and is modified to
use this new helper function.
Deprecation/Compatibility:
dfdlx:repType can no longer reference primitive types (e.g. xs:int).
Instead, a global simple type definition should be created with that has
a base of the primitive type.
DAFFODIL-2211
---
.../org/apache/daffodil/core/dsom/SchemaSet.scala | 15 +++++++++++
.../apache/daffodil/core/dsom/SimpleTypes.scala | 16 +++++------
.../core/grammar/ElementBaseGrammarMixin.scala | 9 +------
.../extensions/type_calc/inputTypeCalc.tdml | 31 ++++++++++++++++++++++
.../extensions/TestInputTypeValueCalc.scala | 2 ++
5 files changed, 55 insertions(+), 18 deletions(-)
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 88dd0aa2d..10c09f4f3 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
@@ -425,6 +425,21 @@ final class SchemaSet private (
_.getGlobalSimpleTypeDef(refQName.local)
}
+ def getGlobalSimpleTypeDefNoPrim(
+ refQName: RefQName,
+ prop: String,
+ context: ThrowsSDE,
+ ): GlobalSimpleTypeDef = {
+ val gstd = getGlobalSimpleTypeDef(refQName)
+ gstd.getOrElse {
+ val isPrimitive = getPrimitiveType(refQName).isDefined
+ val msg =
+ if (isPrimitive) s"The $prop property cannnot resolve to a primitive
type: $refQName"
+ else s"Failed to resolve $prop to a global simpleType definition:
$refQName"
+ context.schemaDefinitionError(msg)
+ }
+ }
+
def getGlobalComplexTypeDef(refQName: RefQName) =
getSchema(refQName.namespace).flatMap {
_.getGlobalComplexTypeDef(refQName.local)
}
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 e102e2999..c9183bc84 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
@@ -387,17 +387,13 @@ abstract class SimpleTypeDefBase(xml: Node,
lexicalParent: SchemaComponent)
}.value
override lazy val optRepType: Option[SimpleTypeBase with NamedMixin] =
LV('optRepType) {
- val optRepTypeDef =
optRepTypeQName.flatMap(schemaSet.getGlobalSimpleTypeDef(_))
- val optRepPrimType = optRepTypeQName.flatMap(schemaSet.getPrimitiveType(_))
- Assert.invariant(!(optRepPrimType.isDefined && optRepTypeDef.isDefined))
- if (optRepTypeQName.isDefined) {
- schemaDefinitionUnless(
- optRepTypeDef.isDefined || optRepPrimType.isDefined,
- s"Cannot find reptype ${optRepTypeQNameString.get}",
- )
+ val optRepTypeDef = optRepTypeQName.map { qname =>
+ // throws an SDE if the simple type def is not found or if it is not a
simple type (e.g. a
+ // primitive type)
+ schemaSet.getGlobalSimpleTypeDefNoPrim(qname, "dfdlx:repType", this)
}
- optRepTypeDef.orElse(optRepPrimType)
- }.toOption.flatten
+ optRepTypeDef
+ }.value
override lazy val optRepValueSet: Option[RepValueSet] =
optRepTypeDef.flatMap(repType => {
val primType: PrimType = repType.primType
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
index b373bafe2..eaaf4d542 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala
@@ -96,14 +96,7 @@ trait ElementBaseGrammarMixin
// We need to resolve the global simple type of the prefix length type
// because we need to create a detached element with the same schema
// document/parent of the GSTD.
- schemaSet
- .getGlobalSimpleTypeDef(prefixLengthType)
- .getOrElse(
- schemaDefinitionError(
- "Failed to resolve dfdl:prefixLengthType=\"%s\" to a simpleType",
- prefixLengthType.toQNameString,
- ),
- )
+ schemaSet.getGlobalSimpleTypeDefNoPrim(prefixLengthType,
"dfdl:prefixLengthType", this)
}.value
lazy val prefixedLengthElementDecl: PrefixLengthQuasiElementDecl =
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc.tdml
index ab64f6e67..812ee9f16 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc.tdml
@@ -327,4 +327,35 @@
</tdml:errors>
</tdml:unparserTestCase>
+ <tdml:defineSchema name="inputTypeCalc-InvalidRepType.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="primitiveRep_invalid" dfdlx:repType="xs:int">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="zero" dfdlx:repValues="0" />
+ <xs:enumeration value="one" dfdlx:repValues="1" />
+ <xs:enumeration value="two" dfdlx:repValues="2" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="root" type="primitiveRep_invalid" />
+
+ </tdml:defineSchema>
+
+ <tdml:parserTestCase name="primitiveRep_invalid_01"
+ root="root" model="inputTypeCalc-InvalidRepType.dfdl.xsd">
+ <tdml:document>1</tdml:document>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>dfdlx:repType</tdml:error>
+ <tdml:error>primitive type</tdml:error>
+ <tdml:error>xs:int</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
</tdml:testSuite>
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 0be2137c0..d42fa3592 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
@@ -65,4 +65,6 @@ class TestInputTypeValueCalc {
@Test def test_unparseValueNotFound_2(): Unit = {
runner.runOneTest("unparseValueNotFound_2")
}
+
+ @Test def test_primitiveRep_invalid(): Unit = {
runner.runOneTest("primitiveRep_invalid_01") }
}