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") }
 }

Reply via email to