This is an automated email from the ASF dual-hosted git repository.

mbeckerle 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 ff9ba411a Refactor NodeInfo.PrimType. Add DFDLPrimType Java enum.
ff9ba411a is described below

commit ff9ba411aefa8635831680f573c8f2670828421d
Author: Michael Beckerle <[email protected]>
AuthorDate: Mon Feb 12 18:45:33 2024 -0500

    Refactor NodeInfo.PrimType. Add DFDLPrimType Java enum.
    
    Bunch of cleanups of NodeInfo dead or little-used code.
    
    optPrimType is now available on all TypeNodes and associated
    Kind Scala types. (eliminates list searching to find primType)
    
    Contributes to, but does not complete work on layers API.
    
    DAFFODIL-2845
---
 .../daffodil/core/dsom/CompiledExpression.scala    |  62 +++--
 .../daffodil/core/dsom/RuntimePropertyMixins.scala |   5 -
 .../apache/daffodil/core/dsom/SimpleTypes.scala    |   2 +-
 .../daffodil/io/LimitingJavaIinputStreams.scala    |   4 +-
 .../scala/org/apache/daffodil/lib/util/Delay.scala |  82 ++++--
 .../org/apache/daffodil/lib/util/TestDelay.scala   |  79 ++++++
 .../daffodil/runtime1/api/DFDLPrimType.java}       |  37 ++-
 .../apache/daffodil/runtime1/api/Metadata.scala    |  80 ++----
 .../apache/daffodil/runtime1/dpath/NodeInfo.scala  | 289 +++++++++------------
 .../runtime1/dsom/CompiledExpression1.scala        |   2 -
 .../runtime1/infoset/JDOMInfosetOutputter.scala    |   4 +-
 .../runtime1/infoset/JsonInfosetOutputter.scala    |   4 +-
 .../runtime1/infoset/SAXInfosetOutputter.scala     |   4 +-
 .../infoset/ScalaXMLInfosetOutputter.scala         |   4 +-
 .../runtime1/infoset/W3CDOMInfosetOutputter.scala  |   8 +-
 .../daffodil/runtime1/processors/RuntimeData.scala |  11 +-
 16 files changed, 358 insertions(+), 319 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/CompiledExpression.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/CompiledExpression.scala
index c3c47ec59..47e9b1ee4 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/CompiledExpression.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/CompiledExpression.scala
@@ -17,16 +17,18 @@
 
 package org.apache.daffodil.core.dsom
 
-import java.lang.{ Boolean => JBoolean, Long => JLong }
+import java.lang.{ Boolean => JBoolean }
+import java.lang.{ Long => JLong }
 import scala.xml.NamespaceBinding
 
 import org.apache.daffodil.core.dpath._
+import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.schema.annotation.props.Found
 import org.apache.daffodil.lib.util.DPathUtil
 import org.apache.daffodil.lib.xml.NamedQName
 import org.apache.daffodil.runtime1.BasicComponent
 import org.apache.daffodil.runtime1.dpath.NodeInfo
-import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
+import org.apache.daffodil.runtime1.dpath.NodeInfo.AnyAtomic
 import org.apache.daffodil.runtime1.dsom._
 import org.apache.daffodil.runtime1.infoset.DataValue.DataValuePrimitive
 
@@ -251,33 +253,39 @@ class ExpressionCompiler[T <: AnyRef] extends 
ExpressionCompilerBase[T] {
     // required. If something is passed in that does not convert to the
     // expected type it will result in error.
 
-    // must be able to convert this to a primitive type
-    val maybePrimType = PrimType.fromNodeInfo(nodeInfoKind)
-    if (maybePrimType.isEmpty) {
-      val msg = "No known primitive type to convert logical value to: %s"
-      compileInfoWhereExpressionWasLocated.SDE(msg, nodeInfoKind)
-    }
+    nodeInfoKind match {
+      case atomic: AnyAtomic.Kind => {
 
-    // remove the leading escape curly brace if it exists
-    val literal =
-      if (exprOrLiteral.startsWith("{{")) exprOrLiteral.tail
-      else exprOrLiteral
+        // remove the leading escape curly brace if it exists
+        val literal =
+          if (exprOrLiteral.startsWith("{{")) exprOrLiteral.tail
+          else exprOrLiteral
 
-    val logical: DataValuePrimitive =
-      try {
-        maybePrimType.get.fromXMLString(literal)
-      } catch {
-        case e: Exception => {
-          val msg = "Unable to convert logical value \"%s\" to %s: %s"
-          compileInfoWhereExpressionWasLocated.SDE(
-            msg,
-            exprOrLiteral,
-            nodeInfoKind,
-            e.getMessage,
-          )
-        }
-      }
+        val logical: DataValuePrimitive =
+          try {
+            atomic.primType.fromXMLString(literal)
+          } catch {
+            case e: Exception => {
+              val msg = "Unable to convert logical value \"%s\" to %s: %s"
+              compileInfoWhereExpressionWasLocated.SDE(
+                msg,
+                exprOrLiteral,
+                nodeInfoKind,
+                e.getMessage,
+              )
+            }
+          }
 
-    new ConstantExpression[T](qn, nodeInfoKind, 
logical.getAnyRef.asInstanceOf[T])
+        new ConstantExpression[T](qn, nodeInfoKind, 
logical.getAnyRef.asInstanceOf[T])
+      }
+      // $COVERAGE-OFF$
+      case _ => {
+        val msg = "No known primitive type to convert logical value to: %s"
+        Assert.invariantFailed(
+          msg + 
compileInfoWhereExpressionWasLocated.schemaFileLocation.toString,
+        )
+      }
+      // $COVERAGE-ON$
+    }
   }
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala
index 81a94ba22..82ad4a720 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala
@@ -884,11 +884,6 @@ trait LayeringRuntimeValuedPropertiesMixin extends 
RawLayeringRuntimeValuedPrope
     )
   }
 
-  //  final lazy val layerBoundaryMarkEv = {
-  //    if (maybeLayerBoundaryMarkEv.isEmpty) layerBoundaryMarkRaw // must be 
defined
-  //    maybeLayerBoundaryMarkEv.get
-  //  }
-
   final lazy val maybeLayerBoundaryMarkEv = {
     if (optionLayerBoundaryMarkRaw.isDefined) {
       val ev = new LayerBoundaryMarkEv(layerBoundaryMarkExpr, tci)
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 fe6e78d17..7541ee495 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
@@ -45,7 +45,7 @@ sealed trait SimpleTypeBase extends TypeBase with 
SimpleTypeView {
 
 /**
  * PrimType nodes are part of the runtime. For compilation, we need a notion
- * of primitive type that derives from the same base a SimpleTypeBase and
+ * of primitive type that derives from the same base as SimpleTypeBase and
  * ComplexTypeBase, and it needs to have methods that take and return
  * compiler-only object types; hence we can't define a base in the runtime
  * because it can't have those methods; hence, can't achieve the
diff --git 
a/daffodil-io/src/main/scala/org/apache/daffodil/io/LimitingJavaIinputStreams.scala
 
b/daffodil-io/src/main/scala/org/apache/daffodil/io/LimitingJavaIinputStreams.scala
index fc4d71946..f007fc128 100644
--- 
a/daffodil-io/src/main/scala/org/apache/daffodil/io/LimitingJavaIinputStreams.scala
+++ 
b/daffodil-io/src/main/scala/org/apache/daffodil/io/LimitingJavaIinputStreams.scala
@@ -41,7 +41,7 @@ class ExplicitLengthLimitingStream(in: InputStream, limit: 
Long) extends FilterI
 
   private var numRemaining = limit
 
-  override def read(buf: Array[Byte], off: Int, len: Int) = {
+  override def read(buf: Array[Byte], off: Int, len: Int): Int = {
     Assert.invariant(numRemaining >= 0)
     if (numRemaining == 0) -1
     else if (len == 0) 0
@@ -97,7 +97,7 @@ object BoundaryMarkLimitingStream {
     boundaryMark: String,
     charset: Charset,
     targetChunkSize: Int = 32 * 1024,
-  ) = {
+  ): InputStream = {
 
     Assert.usage(targetChunkSize >= 1)
     Assert.usage(boundaryMark.length >= 1)
diff --git 
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Delay.scala 
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Delay.scala
index f0a9a2455..00cf0aca8 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Delay.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Delay.scala
@@ -22,6 +22,8 @@ import org.apache.daffodil.lib.exceptions.Assert
 /**
  * Delay[T]
  *
+ * Used to create cyclic objects without side-effects.
+ *
  * This Delayed evaluation technique is an alternative to staggered
  * multi-stage factories, or currying. Turns out currying works fine in
  * Scala for functions, but not for class constructors, so it's easier to
@@ -65,7 +67,7 @@ import org.apache.daffodil.lib.exceptions.Assert
  *
  * }}}
  */
-final class Delay[T] private (private var box: Delay.Box[T], sym: Symbol)
+final class Delay[T] private (private var box: Delay.Box[T], ctxt1: AnyRef)
   extends PreSerialization {
   //
   // This trick of taking another object on a var, and
@@ -97,20 +99,23 @@ final class Delay[T] private (private var box: 
Delay.Box[T], sym: Symbol)
   /**
    * Create a string representation. Does not force the value to be computed.
    */
-  override def toString = {
-    val bodyString = if (hasValue) ", " + value.toString else ""
-    val objString =
-      if (hasValue) ""
-      else {
-        box
+  override def toString: String = {
+    val str =
+      if (hasValue) {
+        if (ctxt1 ne null)
+          s"Delay(${Delay.nameOrValue(ctxt1)}, $value)"
+        else
+          s"Delay($value)"
+      } else {
+        s"Delay($box)"
       }
-    "Delay(" + sym + ", " + objString + bodyString + ")"
+    str
   }
 
   override def preSerialization = {
     if (!hasValue) {
       Assert.invariant(box ne null)
-      val msg = s"No value for delay. Containing object not initialized? ID 
Symbol:$sym " +
+      val msg = s"No value for delay. Containing object not initialized? ID 
Symbol:$ctxt1 " +
         s"object ${box}"
       Assert.invariantFailed(msg)
     }
@@ -121,32 +126,71 @@ final class Delay[T] private (private var box: 
Delay.Box[T], sym: Symbol)
   final private def writeObject(out: java.io.ObjectOutputStream): Unit = 
serializeObject(out)
 }
 
+/**
+ * Factory for Delay[T] objects. Used to create cyclic structures without 
using side-effects.
+ */
 object Delay {
 
   /**
    * Create a delayed expression object.
    *
+   * @param ctxt1 Used for debugging only. ctxt1.toString is used in display 
of these object.
+   *              Can be null if not needed.
+   * @param ctxt2 Used for debugging only. ctxt2.toString is used in display 
of these objects.
+   *              Can be null if not needed.
    * @param delayedExpression an argument expression which will not be 
evaluated until required
    * @tparam T type of the argument. (Usually inferred by Scala.)
    * @return the Delay object
    */
-  def apply[T](sym: Symbol, obj: AnyRef, delayedExpression: => T) = {
-    new Delay(new Box(sym, obj, delayedExpression), sym)
+  def apply[T](ctxt1: AnyRef, ctxt2: AnyRef, delayedExpression: => T): 
Delay[T] = {
+    new Delay(new Box(ctxt1, ctxt2, delayedExpression), ctxt1)
   }
 
   /**
-   * Specifically, this is NOT serializable.
+   * Two-arg version to create a delayed expression object.
+   * @param ctxt1 Used for debugging only. ctxt1.toString is used in display 
of these object.
+   *              Can be null if not needed.
+   * @param delayedExpression an argument expression which will not be 
evaluated until required
+   * @tparam T type of the argument. (Usually inferred by Scala.)
+   * @return the Delay object.
+   */
+  def apply[T](ctxt1: AnyRef, delayedExpression: => T): Delay[T] =
+    new Delay(new Box(ctxt1, null, delayedExpression), ctxt1)
+
+  private def nameOrValue(x: AnyRef) = x match {
+    case d: NamedMixinBase => d.diagnosticDebugName
+    case _ => x
+  }
+
+  /**
+   * Box object to hold delayed expression.
+   *
+   * Needed so that we can look at Delay objects in the debugger and
+   * printed output without forcing the evaluation of their delayed contents.
+   *
+   * Also potentially helps with discarding everything Scala needs
+   * to implement Delays, once they have been forced.
+   *
+   * Note: this is NOT serializable, on purpose.
    * Serialization must force all Delay objects.
+   * @param ctxt1 Used for debugging only. ctxt1.toString is used in display 
of these object.
+   *              Can be null if not needed.
+   * @param ctxt2 Used for debugging only. ctxt2.toString is used in display 
of these objects.
+   *              Can be null if not needed.
+   * @param delayedExpression an argument expression which will not be 
evaluated until required
+   * @tparam T
    */
-  private class Box[T](val sym: Symbol, val obj: AnyRef, delayedExpression: => 
T) {
+  private class Box[T](val ctxt1: AnyRef, val ctxt2: AnyRef, 
delayedExpression: => T) {
     lazy val value = delayedExpression
 
-    override def toString() = {
-      val desc = obj match {
-        case d: NamedMixinBase => "(" + d.diagnosticDebugName + ")"
-        case _ => ""
-      }
-      "box(" + obj.hashCode() + desc + ")"
+    private lazy val str = {
+      val ctxtList = Seq(Option(ctxt1), Option(ctxt2)).flatten.distinct
+      val descList: Seq[_] = ctxtList.map { nameOrValue(_) }
+      val desc =
+        if (descList.isEmpty) "@" + hashCode().toString
+        else descList.mkString("(", ", ", ")")
+      s"box$desc"
     }
+    override def toString() = str
   }
 }
diff --git 
a/daffodil-lib/src/test/scala/org/apache/daffodil/lib/util/TestDelay.scala 
b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/util/TestDelay.scala
new file mode 100644
index 000000000..355b8683e
--- /dev/null
+++ b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/util/TestDelay.scala
@@ -0,0 +1,79 @@
+/*
+ *  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.lib.util
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+class TestDelay {
+  object Context1 extends NamedMixinBase
+  object Context2 extends NamedMixinBase
+
+  @Test def testDelayToString1(): Unit = {
+    val d = Delay("context1", "context2", 1 + 2)
+    val ds = d.toString
+    val v = d.value
+    assertEquals("3", v.toString)
+    val dsv = d.toString
+    assertEquals("Delay(box(context1, context2))", ds)
+    assertEquals("Delay(context1, 3)", dsv)
+  }
+
+  @Test def testDelayToString2(): Unit = {
+    val d = Delay(Context1, Context2, 1 + 2)
+    val ds = d.toString
+    val v = d.value
+    assertEquals("3", v.toString)
+    val dsv = d.toString
+    assertEquals("Delay(box(Context1, Context2))", ds)
+    assertEquals("Delay(Context1, 3)", dsv)
+  }
+
+  @Test def testDelayToString3(): Unit = {
+    val d = Delay(Context1, 1 + 2)
+    val ds = d.toString
+    val v = d.value
+    assertEquals("3", v.toString)
+    val dsv = d.toString
+    assertEquals("Delay(box(Context1))", ds)
+    assertEquals("Delay(Context1, 3)", dsv)
+  }
+
+  @Test def testDelayToString4(): Unit = {
+    val d = Delay(null, Context2, 1 + 2)
+    val ds = d.toString
+    val v = d.value
+    assertEquals("3", v.toString)
+    val dsv = d.toString
+    assertEquals("Delay(box(Context2))", ds)
+    assertEquals("Delay(3)", dsv)
+  }
+
+  @Test def testDelayToString5(): Unit = {
+    val d = Delay(null, null, 1 + 2)
+    val ds = d.toString
+    val v = d.value
+    assertEquals("3", v.toString)
+    val dsv = d.toString
+    assertTrue(ds.startsWith("Delay(box@"))
+    assertTrue(ds.endsWith(")"))
+    assertEquals("Delay(3)", dsv)
+  }
+
+}
diff --git 
a/daffodil-runtime1/src/test/scala/org/apache/daffodil/runtime1/dpath/TestNodeInfo.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/DFDLPrimType.java
similarity index 63%
rename from 
daffodil-runtime1/src/test/scala/org/apache/daffodil/runtime1/dpath/TestNodeInfo.scala
rename to 
daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/DFDLPrimType.java
index 7f4f8ad32..64a1657d6 100644
--- 
a/daffodil-runtime1/src/test/scala/org/apache/daffodil/runtime1/dpath/TestNodeInfo.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/DFDLPrimType.java
@@ -14,16 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.daffodil.runtime1.api;
 
-package org.apache.daffodil.runtime1.dpath
-
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class TestNodeInfo {
-
-  @Test def test_nodeInfoCanBeConstructed(): Unit = {
-    assertTrue(NodeInfo.isXDerivedFromY("Byte", "Long"))
-  }
+/**
+ * An enumeration of all DFDL's simple types.
+ * <p/>
+ * Intended to be easily used from Java code calling Daffodil APIs.
+ */
+public enum DFDLPrimType {
 
+    String,
+    Int,
+    Byte,
+    Short,
+    Long,
+    Integer,
+    Decimal,
+    UnsignedInt,
+    UnsignedByte,
+    UnsignedShort,
+    UnsignedLong,
+    NonNegativeInteger,
+    Double,
+    Float,
+    HexBinary,
+    AnyURI,
+    Boolean,
+    DateTime,
+    Date,
+    Time
 }
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/Metadata.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/Metadata.scala
index f63cbcaf9..6686b6968 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/Metadata.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/api/Metadata.scala
@@ -17,12 +17,8 @@
 package org.apache.daffodil.runtime1.api
 
 import java.lang.{ Long => JLong }
-import scala.collection.JavaConverters._
 import scala.xml.NamespaceBinding
 
-import org.apache.daffodil.runtime1.dpath.NodeInfo
-import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
-
 /**
  * This is the supportable API for access to the RuntimeData structures
  * which provide access to static information about a given compiled schema
@@ -155,58 +151,11 @@ trait ComplexElementMetadata extends ElementMetadata {
  */
 trait SimpleElementMetadata extends ElementMetadata {
 
-  def primitiveType: PrimitiveType
-}
-
-/**
- * Instances are static objects that represent the DFDL primitive types.
- */
-trait PrimitiveType {
-  def name: String
-}
-
-/**
- * Static methods related to PrimitiveType objects
- */
-object PrimitiveType {
-
-  private lazy val _list: java.util.List[PrimitiveType] =
-    NodeInfo.allDFDLTypes.asInstanceOf[Seq[PrimitiveType]].asJava
-
   /**
-   * Get a primitive type given a name string.
-   *
-   * @param name lookup key. Case insensitive.
-   * @return the PrimitiveType with that name, or null if there is no such 
primitive type.
+   * Primitive Type enum usable from Java
+   * @return
    */
-  def fromName(name: String): PrimitiveType =
-    NodeInfo.primitiveTypeFromName(name)
-
-  /**
-   * A list of all the primitive type objects.
-   */
-  def list: java.util.List[PrimitiveType] = _list
-
-  val String: PrimitiveType = PrimType.String
-  val Int: PrimitiveType = PrimType.Int
-  val Byte: PrimitiveType = PrimType.Byte
-  val Short: PrimitiveType = PrimType.Short
-  val Long: PrimitiveType = PrimType.Long
-  val Integer: PrimitiveType = PrimType.Integer
-  val Decimal: PrimitiveType = PrimType.Decimal
-  val UnsignedInt: PrimitiveType = PrimType.UnsignedInt
-  val UnsignedByte: PrimitiveType = PrimType.UnsignedByte
-  val UnsignedShort: PrimitiveType = PrimType.UnsignedShort
-  val UnsignedLong: PrimitiveType = PrimType.UnsignedLong
-  val NonNegativeInteger: PrimitiveType = PrimType.NonNegativeInteger
-  val Double: PrimitiveType = PrimType.Double
-  val Float: PrimitiveType = PrimType.Float
-  val HexBinary: PrimitiveType = PrimType.HexBinary
-  val AnyURI: PrimitiveType = PrimType.AnyURI
-  val Boolean: PrimitiveType = PrimType.Boolean
-  val DateTime: PrimitiveType = PrimType.DateTime
-  val Date: PrimitiveType = PrimType.Date
-  val Time: PrimitiveType = PrimType.Time
+  def dfdlType: DFDLPrimType
 }
 
 /**
@@ -249,6 +198,10 @@ abstract class MetadataHandler() {
 
   /**
    * Called for simple type element metadata (for declarations or references)
+   *
+   * There are no separate start/end methods for simple element declarations.
+   *
+   * @param m the simple element metadata for the element declaration.
    */
   def simpleElementMetadata(m: SimpleElementMetadata): Unit
 
@@ -257,6 +210,7 @@ abstract class MetadataHandler() {
    *
    * Subsequent calls will be for the model group making up the content
    * of the element.
+   * @param m the complex element metadata for the element declaration that is 
starting
    */
   def startComplexElementMetadata(m: ComplexElementMetadata): Unit
 
@@ -265,41 +219,41 @@ abstract class MetadataHandler() {
    *
    * This is called after all the calls corresponding to the content of the
    * complex type element.
-   * @param m
+   * @param m the complex element metadata for the element declaration that is 
ending
    */
   def endComplexElementMetadata(m: ComplexElementMetadata): Unit
 
   /**
-   * Called for sequence groups.
+   * Called for sequence group definitions.
    *
    * Subsequent calls will be for the content of the sequence.
-   * @param m
+   * @param m the sequence metadata for the sequence definition that is 
starting
    */
   def startSequenceMetadata(m: SequenceMetadata): Unit
 
   /**
-   * Called for sequence groups.
+   * Called for sequence group definitions.
    *
    * This is called after all the calls corresponding to the content
    * of the sequence group.
-   * @param m
+   * @param m the sequence metadata for the sequence definition that is ending
    */
   def endSequenceMetadata(m: SequenceMetadata): Unit
 
   /**
-   * Called for choice groups.
+   * Called for choice group definitions.
    *
    * Subsequent calls will be for the content of the choice.
-   * @param m
+   * @param m the choice metadata for the choice definition that is starting
    */
   def startChoiceMetadata(m: ChoiceMetadata): Unit
 
   /**
-   * Called for choice groups.
+   * Called for choice group definitions.
    *
    * This is called after all the calls corresponding to the content
    * of the choice group.
-   * @param m
+   * @param m the choice metadata for the choice definition that is ending
    */
   def endChoiceMetadata(m: ChoiceMetadata): Unit
 
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
index 759ae01e6..478daa63a 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
@@ -17,6 +17,7 @@
 
 package org.apache.daffodil.runtime1.dpath
 
+import java.io.Serializable
 import java.lang.{ Byte => JByte }
 import java.lang.{ Double => JDouble }
 import java.lang.{ Float => JFloat }
@@ -27,9 +28,7 @@ import java.math.{ BigDecimal => JBigDecimal }
 import java.math.{ BigInteger => JBigInt }
 import java.net.URI
 import java.net.URISyntaxException
-import scala.collection.JavaConverters._
 
-import org.apache.daffodil.lib.calendar.DFDLCalendar
 import org.apache.daffodil.lib.calendar.DFDLDateConversion
 import org.apache.daffodil.lib.calendar.DFDLDateTimeConversion
 import org.apache.daffodil.lib.calendar.DFDLTimeConversion
@@ -43,10 +42,8 @@ import org.apache.daffodil.lib.util.Numbers.asBigInt
 import org.apache.daffodil.lib.xml.GlobalQName
 import org.apache.daffodil.lib.xml.NoNamespace
 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.api
-import org.apache.daffodil.runtime1.api.PrimitiveType
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.dsom.walker._
 import org.apache.daffodil.runtime1.infoset.DataValue.DataValueBigDecimal
 import org.apache.daffodil.runtime1.infoset.DataValue.DataValueBigInt
@@ -65,8 +62,6 @@ import 
org.apache.daffodil.runtime1.infoset.DataValue.DataValueShort
 import org.apache.daffodil.runtime1.infoset.DataValue.DataValueTime
 import org.apache.daffodil.runtime1.infoset.DataValue.DataValueURI
 
-object TypeNode
-
 /**
  * We need to have a data structure that lets us represent a type, and
  * its relationship (conversion, subtyping) to other types.
@@ -85,16 +80,16 @@ sealed abstract class TypeNode private (
 ) extends Serializable
   with NodeInfo.Kind {
 
-  def this(sym: Symbol, parents: => Seq[NodeInfo.Kind], children: => 
Seq[NodeInfo.Kind]) =
-    this(Delay(sym, TypeNode, parents), Delay(sym, TypeNode, children))
+  def this(parents: => Seq[NodeInfo.Kind], children: => Seq[NodeInfo.Kind]) =
+    this(Delay("TypeNode", parents), Delay("TypeNode", children))
 
-  def this(sym: Symbol, parentArg: NodeInfo.Kind, childrenArg: => 
Seq[NodeInfo.Kind]) =
-    this(Delay(sym, TypeNode, Seq(parentArg)), Delay(sym, TypeNode, 
childrenArg))
+  def this(parentArg: NodeInfo.Kind, childrenArg: => Seq[NodeInfo.Kind]) =
+    this(Delay("TypeNode", Seq(parentArg)), Delay("TypeNode", childrenArg))
 
-  def this(sym: Symbol, parentArg: => NodeInfo.Kind) =
+  def this(parentArg: => NodeInfo.Kind) =
     this(
-      Delay(sym, TypeNode, Seq(parentArg)),
-      Delay(sym, TypeNode, Seq[NodeInfo.Kind](NodeInfo.Nothing)),
+      Delay("TypeNode", Seq(parentArg)),
+      Delay("TypeNode", Seq[NodeInfo.Kind](NodeInfo.Nothing)),
     )
 
   /**
@@ -121,14 +116,15 @@ sealed abstract class TypeNode private (
  * types (like AnyAtomic, or AnyDateTimeType) that surround them.
  */
 sealed abstract class PrimTypeNode(
-  sym: Symbol,
+  val dfdlType: DFDLPrimType,
   parent: NodeInfo.Kind,
   childrenArg: => Seq[NodeInfo.Kind],
-) extends TypeNode(sym, parent, childrenArg)
-  with NodeInfo.PrimType
-  with api.PrimitiveType {
+) extends TypeNode(parent, childrenArg)
+  with NodeInfo.PrimType {
+
+  def this(javaType: DFDLPrimType, parent: NodeInfo.Kind) =
+    this(javaType, parent, Seq(NodeInfo.Nothing))
 
-  def this(sym: Symbol, parent: NodeInfo.Kind) = this(sym, parent, 
Seq(NodeInfo.Nothing))
 }
 
 class InvalidPrimitiveDataException(msg: String, cause: Throwable = null)
@@ -151,13 +147,13 @@ class InvalidPrimitiveDataException(msg: String, cause: 
Throwable = null)
  * NodeInfo.Kind (type of any of these enums)
  * NodeInfo.Number.Kind (type of just the number variants)
  * NodeInfo.Value.Kind (type of just the value variants)
- * The enums themselves are just NodeInfo.Decimal (for example)
+ * The enums themselves are just PrimType.Decimal (for example)
  *
- * Note that you can talk about types using type node objects: E.g., 
NodeInfo.Number.
+ * Note that you can talk about types using type node objects: E.g., 
PrimType.Number.
  * But you can also use Scala typing to ask whether a particular type object is
  * a subtype of another: e.g.
  * <pre>
- * val x = NodeInfo.String
+ * val x = PrimType.String
  * val aa = NodeInfo.AnyAtomic
  * x.isSubTypeOf(aa) // true. Ordinary way to check. Navigates our data 
structure.
  * x.isInstanceOf[NodeInfo.AnyAtomic.Kind] // true. Uses scala type checking
@@ -175,7 +171,7 @@ object NodeInfo extends Enum {
   /**
    * Cyclic structures require initialization
    */
-  lazy val initialize: Boolean = {
+  private lazy val initialize: Boolean = {
     allTypes.foreach {
       _.initialize
     }
@@ -183,12 +179,15 @@ object NodeInfo extends Enum {
   }
 
   // Primitives are not "global" because they don't appear in any schema 
document
-  sealed trait PrimType extends AnyAtomic.Kind {
+
+  sealed trait PrimType extends PrimTypeKind {
 
     def globalQName: GlobalQName
+    def dfdlType: DFDLPrimType
 
     /**
-     * When class name is isomorphic to the type name, compute automatically.
+     * When class name is isomorphic to the type name (with initial lower 
case),
+     * compute automatically.
      */
     override lazy val name: String = {
       val cname = super.name
@@ -198,40 +197,13 @@ object NodeInfo extends Enum {
     }
 
     def isError: Boolean = false
-    def primType = this
-
-    def fromXMLString(s: String): DataValuePrimitive
-
-    override def toString = name
-  }
 
-  private def getTypeNode(name: String) = {
-    val namelc = name.toLowerCase()
-    allTypes.find(stn => stn.lcaseName == namelc)
-  }
+    private lazy val optPrimType_ = Some(this)
+    override def optPrimType: Option[PrimType] = optPrimType_
 
-  /**
-   * For Java API use, we have a very restricted trait api.PrimitiveType
-   * mixed into PrimTypeNode, so that we can hand PrimTypeNode as result
-   * from methods callable from Java without exposing all of PrimType's
-   * implementation.
-   * @param name lookup key, case insensitive
-   * @return an api.PrimitiveType, or null if there is no type with that name.
-   */
-  def primitiveTypeFromName(name: String): PrimitiveType = {
-    allDFDLTypesLookupTable.get(name)
-  }
+    def fromXMLString(s: String): DataValuePrimitive
 
-  def isXDerivedFromY(nameX: String, nameY: String): Boolean = {
-    if (nameX == nameY) true
-    else {
-      getTypeNode(nameX) match {
-        case Some(stn) => {
-          stn.doesParentListContain(nameY)
-        }
-        case None => false
-      }
-    }
+    override def toString: String = name
   }
 
   sealed trait Kind extends EnumValueType with PrimTypeView {
@@ -241,29 +213,33 @@ object NodeInfo extends Enum {
     def parents: Seq[Kind]
     def children: Seq[Kind]
 
-    final lazy val isHead: Boolean = parents.isEmpty
-    final lazy val lcaseName = name.toLowerCase()
+    /**
+     * The prim type corresponding to this type.
+     * So if this Kind is derived from a PrimType kind, then
+     * this kind should return that prim type object.
+     *
+     * This exists for all Kinds, but is (currently 2024-02-13)
+     * only used on Atomic Kinds, so this base never gets called.
+     * That's ok. It's needed on this base Kind anyway.
+     *
+     * @return None if there is no corresponding prim type.
+     */
+    def optPrimType: Option[PrimType] = None
 
-    final lazy val selfAndAllParents: Set[Kind] = parents.flatMap {
+    private final lazy val selfAndAllParents: Set[Kind] = parents.flatMap {
       _.selfAndAllParents
     }.toSet ++ parents
 
-    // names in lower case
-    lazy val parentList: List[String] = {
-      selfAndAllParents.map { _.lcaseName }.toList
-    }
-
-    def isSubtypeOf(other: Kind) =
+    def isSubtypeOf(other: Kind): Boolean =
       if (this eq other) true
       else selfAndAllParents.contains(other)
 
     def doesParentListContain(typeName: String): Boolean = {
-      val list = parentList.filter(n => n.toLowerCase() == 
typeName.toLowerCase())
-      list.size > 0
+      selfAndAllParents.exists { _.name.equalsIgnoreCase(typeName) }
     }
 
     private val xsScope = <xs:documentation xmlns:xs={
-      XMLUtils.XSD_NAMESPACE.uri.toString()
+      XMLUtils.XSD_NAMESPACE.uri.toString
     }/>.scope
 
     // FIXME: this scope has xs prefix bound, but what if that's not the 
binding
@@ -275,7 +251,6 @@ object NodeInfo extends Enum {
       case pt: PrimTypeNode => QName.createGlobal(name, 
XMLUtils.XSD_NAMESPACE, xsScope)
       case _ => QName.createGlobal(name, NoNamespace, scala.xml.TopScope)
     }
-
   }
   val ClassString = classOf[java.lang.String]
   val ClassIntBoxed = classOf[java.lang.Integer]
@@ -296,26 +271,17 @@ object NodeInfo extends Enum {
   val ClassBooleanBoxed = classOf[java.lang.Boolean]
   val ClassBooleanPrim = classOf[scala.Boolean]
 
-  def fromObject(a: Any) = {
-    a match {
-      case x: String => NodeInfo.String
-      case x: Int => NodeInfo.Int
-      case x: Byte => NodeInfo.Byte
-      case x: Short => NodeInfo.Short
-      case x: Long => NodeInfo.Long
-      case x: JBigInt => NodeInfo.Integer
-      case x: JBigDecimal => NodeInfo.Decimal
-      case x: Double => NodeInfo.Double
-      case x: Float => NodeInfo.Float
-      case x: Array[Byte] => NodeInfo.HexBinary
-      case x: URI => NodeInfo.AnyURI
-      case x: Boolean => NodeInfo.Boolean
-      case x: DFDLCalendar => NodeInfo.DateTime
-      case _ => Assert.usageError("Unsupported object representation type: 
%s".format(a))
-    }
-  }
-
-  def fromClass(jc: Class[_]) = {
+  /**
+   * Used to obtain a corresponding DFDL PrimType object given the
+   * class of a Java/Scala object.
+   *
+   * Note how since Java has no unsigned types that we can never
+   * select a DFDL unsigned prim type object here.
+   *
+   * @param jc the java class
+   * @return the corresponding DFDL PrimType object
+   */
+  def fromClass(jc: Class[_]): Option[PrimType] = {
     val ni = jc match {
       case ClassIntBoxed | ClassIntPrim => Some(NodeInfo.Int)
       case ClassByteBoxed | ClassBytePrim => Some(NodeInfo.Byte)
@@ -338,7 +304,7 @@ object NodeInfo extends Enum {
    * the indexing operation.
    */
   protected sealed trait ArrayKind extends NodeInfo.Kind
-  case object Array extends TypeNode('Array, Nil, Nil) with ArrayKind {
+  case object Array extends TypeNode(Nil, Nil) with ArrayKind {
     sealed trait Kind extends ArrayKind
   }
 
@@ -348,7 +314,7 @@ object NodeInfo extends Enum {
    */
   protected sealed trait AnyTypeKind extends NodeInfo.Kind
   case object AnyType
-    extends TypeNode('AnyType, Nil, Seq(AnySimpleType, Complex, Exists))
+    extends TypeNode(Nil, Seq(AnySimpleType, Complex, Exists))
     with AnyTypeKind {
     sealed trait Kind extends AnyTypeKind
   }
@@ -360,7 +326,6 @@ object NodeInfo extends Enum {
    * every type (except some special singletons like ArrayType).
    */
   lazy val Nothing = new TypeNode(
-    'Nothing,
     Seq(
       Boolean,
       Complex,
@@ -398,7 +363,7 @@ object NodeInfo extends Enum {
    * All complex types are represented by this one type object.
    */
   protected sealed trait ComplexKind extends AnyType.Kind
-  case object Complex extends TypeNode('Complex, AnyType) with ComplexKind {
+  case object Complex extends TypeNode(AnyType) with ComplexKind {
     type Kind = ComplexKind
   }
 
@@ -406,7 +371,7 @@ object NodeInfo extends Enum {
    * For things like fn:exists, fn:empty, dfdl:contentLength
    */
   protected sealed trait ExistsKind extends AnyType.Kind
-  case object Exists extends TypeNode('Exists, AnyType) with AnyTypeKind {
+  case object Exists extends TypeNode(AnyType) with AnyTypeKind {
     type Kind = ExistsKind
   }
 
@@ -420,17 +385,16 @@ object NodeInfo extends Enum {
    * AnyAtomic and AnySimpleType is that AnySimpleType admits XSD unions and 
list types,
    * where AnyAtomic does not?
    */
-  protected sealed trait AnySimpleTypeKind extends AnyType.Kind
-  case object AnySimpleType
-    extends TypeNode('AnySimpleType, AnyType, Seq(AnyAtomic))
-    with AnySimpleTypeKind {
+  protected sealed trait AnySimpleTypeKind extends AnyType.Kind {
+    final def primType: PrimType = optPrimType.get
+  }
+  case object AnySimpleType extends TypeNode(AnyType, Seq(AnyAtomic)) with 
AnySimpleTypeKind {
     type Kind = AnySimpleTypeKind
   }
 
   protected sealed trait AnyAtomicKind extends AnySimpleType.Kind
   case object AnyAtomic
     extends TypeNode(
-      'AnyAtomic,
       AnySimpleType,
       Seq(String, Numeric, Boolean, Opaque, AnyDateTime, AnyURI),
     )
@@ -440,27 +404,27 @@ object NodeInfo extends Enum {
 
   protected sealed trait NumericKind extends AnyAtomic.Kind
   case object Numeric
-    extends TypeNode('Numeric, AnyAtomic, Seq(SignedNumeric, UnsignedNumeric))
+    extends TypeNode(AnyAtomic, Seq(SignedNumeric, UnsignedNumeric))
     with NumericKind {
     type Kind = NumericKind
   }
 
   protected sealed trait SignedNumericKind extends Numeric.Kind
   case object SignedNumeric
-    extends TypeNode('SignedNumeric, Numeric, Seq(Float, Double, Decimal))
+    extends TypeNode(Numeric, Seq(Float, Double, Decimal))
     with SignedNumericKind {
     type Kind = SignedNumericKind
   }
 
   protected sealed trait UnsignedNumericKind extends Numeric.Kind
   case object UnsignedNumeric
-    extends TypeNode('UnsignedNumeric, Numeric, Seq(NonNegativeInteger))
+    extends TypeNode(Numeric, Seq(NonNegativeInteger))
     with UnsignedNumericKind {
     type Kind = UnsignedNumericKind
   }
 
   protected sealed trait OpaqueKind extends AnyAtomic.Kind
-  case object Opaque extends TypeNode('Opaque, AnyAtomic, Seq(HexBinary)) with 
OpaqueKind {
+  case object Opaque extends TypeNode(AnyAtomic, Seq(HexBinary)) with 
OpaqueKind {
     type Kind = OpaqueKind
   }
 
@@ -470,18 +434,21 @@ object NodeInfo extends Enum {
    * strings aren't allowed to be empty strings. Also for properties that 
simply
    * arent allowed to be empty strings (e.g. padChar).
    */
-  protected sealed trait NonEmptyStringKind extends String.Kind
-  case object NonEmptyString extends TypeNode('NonEmptyString, String) with 
NonEmptyStringKind {
+  protected sealed trait NonEmptyStringKind extends String.Kind {
+    override def optPrimType: Option[PrimType] = String.optPrimType
+  }
+  case object NonEmptyString extends TypeNode(String) with NonEmptyStringKind {
     type Kind = NonEmptyStringKind
   }
+
   protected sealed trait ArrayIndexKind extends UnsignedInt.Kind
-  case object ArrayIndex extends TypeNode('ArrayIndex, UnsignedInt) with 
ArrayIndexKind {
+  case object ArrayIndex extends TypeNode(UnsignedInt) with ArrayIndexKind {
     type Kind = ArrayIndexKind
   }
 
   protected sealed trait AnyDateTimeKind extends AnyAtomicKind
   case object AnyDateTime
-    extends TypeNode('AnyDateTime, AnyAtomic, Seq(Date, Time, DateTime))
+    extends TypeNode(AnyAtomic, Seq(Date, Time, DateTime))
     with AnyDateTimeKind {
     type Kind = AnyDateTimeKind
   }
@@ -509,53 +476,30 @@ object NodeInfo extends Enum {
   val Date = PrimType.Date
   val Time = PrimType.Time
 
-  /**
-   * This list of types must be in order of most specific to least, i.e. Byte
-   * inherits from Short, which inherits from Int etc. This is becasue
-   * fromNodeInfo does a find on this list based on isSubtypeOf, which will
-   * return the first successful result.
-   */
-  val allPrims = List(
-    String,
-    Byte,
-    Short,
-    Int,
-    Long,
-    UnsignedByte,
-    UnsignedShort,
-    UnsignedInt,
-    UnsignedLong,
-    NonNegativeInteger,
-    Integer,
-    Float,
-    Double,
-    Decimal,
-    HexBinary,
-    AnyURI,
-    Boolean,
-    DateTime,
-    Date,
-    Time,
-  )
+  protected sealed trait PrimTypeKind extends AnyAtomic.Kind
 
   /**
    * The PrimType objects are a child enum within the overall NodeInfo
    * enum.
    */
   object PrimType {
+    type Kind = PrimTypeKind
 
-    def fromRefQName(refQName: RefQName): Option[PrimType] = {
-      allPrims.find { prim => refQName.matches(prim.globalQName) }
+    private lazy val nameToPrimType: Map[String, PrimType] = {
+      // I'd like to use an immutable Linked hash map here.
+      // So that it's deterministic if it is ever iterated.
+      // But Scala (2.12 anyway) has no such thing.
+      allDFDLTypes.map { ptn => (ptn.name, ptn) }.toMap
     }
 
+    /**
+     * given an initial-lower-case NCName, finds the corresonding PrimType
+     * or None if there is no correponding primitive type.
+     * @param name initial lower case name, without any namespace prefix, of a 
DFDL type
+     * @return
+     */
     def fromNameString(name: String): Option[PrimType] = {
-      allPrims.find { _.name.toLowerCase == name.toLowerCase }
-    }
-
-    def fromNodeInfo(nodeInfo: NodeInfo.Kind): Option[PrimType] = {
-      allPrims.find {
-        nodeInfo.isSubtypeOf(_)
-      }
+      nameToPrimType.get(name)
     }
 
     trait PrimNonNumeric { self: AnyAtomic.Kind =>
@@ -675,7 +619,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait FloatKind extends SignedNumeric.Kind
     case object Float
-      extends PrimTypeNode('Float, SignedNumeric)
+      extends PrimTypeNode(DFDLPrimType.Float, SignedNumeric)
       with FloatKind
       with PrimNumericFloat
       with FloatView {
@@ -696,7 +640,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait DoubleKind extends SignedNumeric.Kind
     case object Double
-      extends PrimTypeNode('Double, SignedNumeric)
+      extends PrimTypeNode(DFDLPrimType.Double, SignedNumeric)
       with DoubleKind
       with PrimNumericFloat
       with DoubleView {
@@ -715,7 +659,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait DecimalKind extends SignedNumeric.Kind
     case object Decimal
-      extends PrimTypeNode('Decimal, SignedNumeric, List(Integer))
+      extends PrimTypeNode(DFDLPrimType.Decimal, SignedNumeric, List(Integer))
       with DecimalKind
       with PrimNumeric
       with DecimalView {
@@ -737,7 +681,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait IntegerKind extends Decimal.Kind
     case object Integer
-      extends PrimTypeNode('Integer, Decimal, List(Long, NonNegativeInteger))
+      extends PrimTypeNode(DFDLPrimType.Integer, Decimal, List(Long, 
NonNegativeInteger))
       with IntegerKind
       with PrimNumeric
       with IntegerView {
@@ -759,7 +703,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait LongKind extends Integer.Kind
     case object Long
-      extends PrimTypeNode('Long, Integer, List(Int))
+      extends PrimTypeNode(DFDLPrimType.Long, Integer, List(Int))
       with LongKind
       with PrimNumericInteger
       with LongView {
@@ -773,7 +717,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait IntKind extends Long.Kind
     case object Int
-      extends PrimTypeNode('Int, Long, List(Short))
+      extends PrimTypeNode(DFDLPrimType.Int, Long, List(Short))
       with IntKind
       with PrimNumericInteger
       with IntView {
@@ -787,7 +731,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait ShortKind extends Int.Kind
     case object Short
-      extends PrimTypeNode('Short, Int, List(Byte))
+      extends PrimTypeNode(DFDLPrimType.Short, Int, List(Byte))
       with ShortKind
       with PrimNumericInteger
       with ShortView {
@@ -801,7 +745,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait ByteKind extends Short.Kind
     case object Byte
-      extends PrimTypeNode('Byte, Short)
+      extends PrimTypeNode(DFDLPrimType.Byte, Short)
       with ByteKind
       with PrimNumericInteger
       with ByteView {
@@ -815,7 +759,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait NonNegativeIntegerKind extends Integer.Kind
     case object NonNegativeInteger
-      extends PrimTypeNode('NonNegativeInteger, Integer, List(UnsignedLong))
+      extends PrimTypeNode(DFDLPrimType.NonNegativeInteger, Integer, 
List(UnsignedLong))
       with NonNegativeIntegerKind
       with PrimNumeric
       with NonNegativeIntegerView {
@@ -837,7 +781,11 @@ object NodeInfo extends Enum {
 
     protected sealed trait UnsignedLongKind extends NonNegativeInteger.Kind
     case object UnsignedLong
-      extends PrimTypeNode('UnsignedLong, NonNegativeInteger, 
List(UnsignedInt))
+      extends PrimTypeNode(
+        DFDLPrimType.UnsignedLong,
+        NonNegativeInteger,
+        List(UnsignedInt),
+      )
       with UnsignedLongKind
       with PrimNumeric
       with UnsignedLongView {
@@ -860,7 +808,11 @@ object NodeInfo extends Enum {
 
     protected sealed trait UnsignedIntKind extends UnsignedLong.Kind
     case object UnsignedInt
-      extends PrimTypeNode('UnsignedInt, UnsignedLong, List(UnsignedShort, 
ArrayIndex))
+      extends PrimTypeNode(
+        DFDLPrimType.UnsignedInt,
+        UnsignedLong,
+        List(UnsignedShort, ArrayIndex),
+      )
       with UnsignedIntKind
       with PrimNumericInteger
       with UnsignedIntView {
@@ -874,7 +826,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait UnsignedShortKind extends UnsignedInt.Kind
     case object UnsignedShort
-      extends PrimTypeNode('UnsignedShort, UnsignedInt, List(UnsignedByte))
+      extends PrimTypeNode(DFDLPrimType.UnsignedShort, UnsignedInt, 
List(UnsignedByte))
       with UnsignedShortKind
       with PrimNumericInteger
       with UnsignedShortView {
@@ -888,7 +840,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait UnsignedByteKind extends UnsignedShort.Kind
     case object UnsignedByte
-      extends PrimTypeNode('UnsignedByte, UnsignedShort)
+      extends PrimTypeNode(DFDLPrimType.UnsignedByte, UnsignedShort)
       with UnsignedByteKind
       with PrimNumericInteger
       with UnsignedByteView {
@@ -902,7 +854,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait StringKind extends AnyAtomic.Kind
     case object String
-      extends PrimTypeNode('String, AnyAtomic, List(NonEmptyString))
+      extends PrimTypeNode(DFDLPrimType.String, AnyAtomic, 
List(NonEmptyString))
       with StringKind
       with StringView {
       type Kind = StringKind
@@ -911,7 +863,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait BooleanKind extends AnySimpleType.Kind
     case object Boolean
-      extends PrimTypeNode('Boolean, AnyAtomic)
+      extends PrimTypeNode(DFDLPrimType.Boolean, AnyAtomic)
       with BooleanKind
       with PrimNonNumeric
       with BooleanView {
@@ -927,7 +879,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait AnyURIKind extends AnySimpleType.Kind
     case object AnyURI
-      extends PrimTypeNode('AnyURI, AnyAtomic)
+      extends PrimTypeNode(DFDLPrimType.AnyURI, AnyAtomic)
       with AnyURIKind
       with PrimNonNumeric
       with AnyURIView {
@@ -937,7 +889,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait HexBinaryKind extends Opaque.Kind
     case object HexBinary
-      extends PrimTypeNode('HexBinary, Opaque)
+      extends PrimTypeNode(DFDLPrimType.HexBinary, Opaque)
       with HexBinaryKind
       with PrimNonNumeric
       with HexBinaryView {
@@ -947,7 +899,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait DateKind extends AnyDateTimeKind
     case object Date
-      extends PrimTypeNode('Date, AnyDateTime)
+      extends PrimTypeNode(DFDLPrimType.Date, AnyDateTime)
       with DateKind
       with PrimNonNumeric
       with DateView {
@@ -959,7 +911,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait DateTimeKind extends AnyDateTimeKind
     case object DateTime
-      extends PrimTypeNode('DateTime, AnyDateTime)
+      extends PrimTypeNode(DFDLPrimType.DateTime, AnyDateTime)
       with DateTimeKind
       with PrimNonNumeric
       with DateTimeView {
@@ -971,7 +923,7 @@ object NodeInfo extends Enum {
 
     protected sealed trait TimeKind extends AnyDateTimeKind
     case object Time
-      extends PrimTypeNode('Time, AnyDateTime)
+      extends PrimTypeNode(DFDLPrimType.Time, AnyDateTime)
       with TimeKind
       with PrimNonNumeric
       with TimeView {
@@ -986,7 +938,7 @@ object NodeInfo extends Enum {
   // The below must be lazy vals because of the recursion between this
   // list and the definition of these type objects above.
   //
-  private lazy val allAbstractTypes = List(
+  private lazy val allAbstractTypes: Seq[TypeNode] = List(
     AnyType,
     AnySimpleType,
     AnyAtomic,
@@ -1001,7 +953,7 @@ object NodeInfo extends Enum {
     Opaque,
     AnyDateTime,
   )
-  lazy val allDFDLTypes = List(
+  private lazy val allDFDLTypes: Seq[PrimTypeNode] = List(
     Float,
     Double,
     Decimal,
@@ -1024,10 +976,7 @@ object NodeInfo extends Enum {
     DateTime,
   )
 
-  private lazy val allDFDLTypesLookupTable: java.util.Map[String, 
PrimitiveType] =
-    allDFDLTypes.map { p => (p.name.toLowerCase, 
p.asInstanceOf[PrimitiveType]) }.toMap.asJava
-
-  lazy val allTypes =
+  private lazy val allTypes: Seq[TypeNode] =
     allDFDLTypes ++ List(
       Complex,
       Array,
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 b842733e6..fa7213bc8 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
@@ -144,8 +144,6 @@ final case class ConstantExpression[+T <: AnyRef](qn: 
NamedQName, kind: NodeInfo
 
   def targetType = kind
 
-  lazy val sourceType: NodeInfo.Kind = NodeInfo.fromObject(value)
-
   override def evaluate(state: ParseOrUnparseState) = value
 
   override def run(dstate: DState) = 
dstate.setCurrentValue(DataValue.unsafeFromAnyRef(value))
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JDOMInfosetOutputter.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JDOMInfosetOutputter.scala
index 9e4664cda..eff17248c 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JDOMInfosetOutputter.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JDOMInfosetOutputter.scala
@@ -21,11 +21,11 @@ import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.MStackOf
 import org.apache.daffodil.lib.util.Maybe
 import org.apache.daffodil.lib.xml.XMLUtils
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.InfosetArray
 import org.apache.daffodil.runtime1.api.InfosetComplexElement
 import org.apache.daffodil.runtime1.api.InfosetElement
 import org.apache.daffodil.runtime1.api.InfosetSimpleElement
-import org.apache.daffodil.runtime1.api.PrimitiveType
 
 class JDOMInfosetOutputter extends InfosetOutputter {
 
@@ -56,7 +56,7 @@ class JDOMInfosetOutputter extends InfosetOutputter {
 
     if (!simple.isNilled) {
       val text =
-        if (simple.metadata.primitiveType == PrimitiveType.String) {
+        if (simple.metadata.dfdlType == DFDLPrimType.String) {
           XMLUtils.remapXMLIllegalCharactersToPUA(simple.getText)
         } else {
           simple.getText
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JsonInfosetOutputter.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JsonInfosetOutputter.scala
index 07560d5d0..35a09a4ae 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JsonInfosetOutputter.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/JsonInfosetOutputter.scala
@@ -21,11 +21,11 @@ import java.nio.charset.StandardCharsets
 
 import org.apache.daffodil.lib.util.Indentable
 import org.apache.daffodil.lib.util.MStackOfBoolean
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.InfosetArray
 import org.apache.daffodil.runtime1.api.InfosetComplexElement
 import org.apache.daffodil.runtime1.api.InfosetElement
 import org.apache.daffodil.runtime1.api.InfosetSimpleElement
-import org.apache.daffodil.runtime1.api.PrimitiveType
 
 import com.fasterxml.jackson.core.io.JsonStringEncoder
 
@@ -101,7 +101,7 @@ class JsonInfosetOutputter private (writer: java.io.Writer, 
pretty: Boolean)
     startElement(simple)
     if (!simple.isNilled) {
       val text =
-        if (simple.metadata.primitiveType == PrimitiveType.String) {
+        if (simple.metadata.dfdlType == DFDLPrimType.String) {
           new String(
             stringEncoder.quoteAsString(simple.getText),
           ) // escapes according to Json spec
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/SAXInfosetOutputter.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/SAXInfosetOutputter.scala
index f33886e9d..e31cbc76f 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/SAXInfosetOutputter.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/SAXInfosetOutputter.scala
@@ -21,11 +21,11 @@ import scala.xml.NamespaceBinding
 
 import org.apache.daffodil.lib.xml.XMLUtils
 import org.apache.daffodil.runtime1.api.DFDL
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.InfosetArray
 import org.apache.daffodil.runtime1.api.InfosetComplexElement
 import org.apache.daffodil.runtime1.api.InfosetElement
 import org.apache.daffodil.runtime1.api.InfosetSimpleElement
-import org.apache.daffodil.runtime1.api.PrimitiveType
 
 import org.xml.sax.ContentHandler
 import org.xml.sax.helpers.AttributesImpl
@@ -67,7 +67,7 @@ class SAXInfosetOutputter(
       doStartElement(simple, contentHandler)
       if (!simple.isNilled) {
         val text =
-          if (simple.metadata.primitiveType == PrimitiveType.String) {
+          if (simple.metadata.dfdlType == DFDLPrimType.String) {
             XMLUtils.remapXMLIllegalCharactersToPUA(simple.getText)
           } else {
             simple.getText
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/ScalaXMLInfosetOutputter.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/ScalaXMLInfosetOutputter.scala
index 65157fdc5..9a433c0e9 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/ScalaXMLInfosetOutputter.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/ScalaXMLInfosetOutputter.scala
@@ -26,11 +26,11 @@ import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.MStackOf
 import org.apache.daffodil.lib.util.Maybe
 import org.apache.daffodil.lib.xml.XMLUtils
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.InfosetArray
 import org.apache.daffodil.runtime1.api.InfosetComplexElement
 import org.apache.daffodil.runtime1.api.InfosetElement
 import org.apache.daffodil.runtime1.api.InfosetSimpleElement
-import org.apache.daffodil.runtime1.api.PrimitiveType
 
 class ScalaXMLInfosetOutputter(showFreedInfo: Boolean = false) extends 
InfosetOutputter {
 
@@ -89,7 +89,7 @@ class ScalaXMLInfosetOutputter(showFreedInfo: Boolean = 
false) extends InfosetOu
     val children =
       if (!isNilled(diSimple) && diSimple.hasValue) {
         val text =
-          if (diSimple.metadata.primitiveType == PrimitiveType.String) {
+          if (diSimple.metadata.dfdlType == DFDLPrimType.String) {
             XMLUtils.remapXMLIllegalCharactersToPUA(diSimple.dataValueAsString)
           } else {
             diSimple.dataValueAsString
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/W3CDOMInfosetOutputter.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/W3CDOMInfosetOutputter.scala
index 12e104914..1ec5bf03b 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/W3CDOMInfosetOutputter.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/W3CDOMInfosetOutputter.scala
@@ -23,15 +23,15 @@ import org.apache.daffodil.lib.exceptions.Assert
 import org.apache.daffodil.lib.util.MStackOf
 import org.apache.daffodil.lib.util.Maybe
 import org.apache.daffodil.lib.xml.XMLUtils
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.InfosetArray
 import org.apache.daffodil.runtime1.api.InfosetComplexElement
 import org.apache.daffodil.runtime1.api.InfosetElement
 import org.apache.daffodil.runtime1.api.InfosetSimpleElement
-import org.apache.daffodil.runtime1.api.PrimitiveType
 
 import org.w3c.dom.Document
 import org.w3c.dom.Element
-import org.w3c.dom.Node;
+import org.w3c.dom.Node
 
 class W3CDOMInfosetOutputter extends InfosetOutputter {
 
@@ -47,7 +47,7 @@ class W3CDOMInfosetOutputter extends InfosetOutputter {
   }
 
   def startDocument(): Unit = {
-    val factory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance();
+    val factory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
     factory.setNamespaceAware(true)
     document = factory.newDocumentBuilder().newDocument()
     stack.push(document)
@@ -66,7 +66,7 @@ class W3CDOMInfosetOutputter extends InfosetOutputter {
 
     if (!se.isNilled) {
       val text =
-        if (se.metadata.primitiveType == PrimitiveType.String) {
+        if (se.metadata.dfdlType == DFDLPrimType.String) {
           XMLUtils.remapXMLIllegalCharactersToPUA(se.getText)
         } else {
           se.getText
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 61eada030..cef3b0544 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
@@ -20,7 +20,6 @@ package org.apache.daffodil.runtime1.processors
 import java.lang.{ Double => JDouble }
 import java.lang.{ Float => JFloat }
 import java.lang.{ Long => JLong }
-import scala.collection.JavaConverters._
 import scala.util.matching.Regex
 import scala.xml.NamespaceBinding
 
@@ -46,16 +45,15 @@ import org.apache.daffodil.lib.xml.StepQName
 import org.apache.daffodil.lib.xml.XMLUtils
 import org.apache.daffodil.runtime1.api.ChoiceMetadata
 import org.apache.daffodil.runtime1.api.ComplexElementMetadata
+import org.apache.daffodil.runtime1.api.DFDLPrimType
 import org.apache.daffodil.runtime1.api.ElementMetadata
 import org.apache.daffodil.runtime1.api.Metadata
 import org.apache.daffodil.runtime1.api.ModelGroupMetadata
-import org.apache.daffodil.runtime1.api.PrimitiveType
 import org.apache.daffodil.runtime1.api.SequenceMetadata
 import org.apache.daffodil.runtime1.api.SimpleElementMetadata
 import org.apache.daffodil.runtime1.api.TermMetadata
 import org.apache.daffodil.runtime1.dpath.NodeInfo
 import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
-import org.apache.daffodil.runtime1.dpath.PrimTypeNode
 import org.apache.daffodil.runtime1.dsom.CompiledExpression
 import org.apache.daffodil.runtime1.dsom.DPathCompileInfo
 import org.apache.daffodil.runtime1.dsom.DPathElementCompileInfo
@@ -698,10 +696,9 @@ sealed class ElementRuntimeData(
 
   def isSimpleType = optPrimType.isDefined
 
-  def primType: PrimTypeNode =
-    optPrimType.asInstanceOf[Option[PrimTypeNode]].orNull
+  def primType: PrimType = optPrimType.orNull
 
-  override def primitiveType: PrimitiveType = 
primType.asInstanceOf[PrimitiveType]
+  override def dfdlType: DFDLPrimType = primType.dfdlType
 
   lazy val schemaURIStringsForFullValidation: Seq[String] =
     schemaURIStringsForFullValidation1.distinct
@@ -756,13 +753,11 @@ sealed abstract class ErrorERD(local: String, 
namespaceURI: String)
     new DPathElementCompileInfo(
       Delay(
         'ErrorERDParents,
-        getClass().getName,
         Seq[DPathElementCompileInfo](),
       ).force, // parentsArg: => Seq[DPathElementCompileInfo],
       null, // variableMap: => VariableMap,
       Delay(
         'ErrorERD,
-        getClass().getName,
         Seq[DPathElementCompileInfo](),
       ).force, // elementChildrenCompileInfoDelay: 
Delay[Seq[DPathElementCompileInfo]],
       null, // namespaces: scala.xml.NamespaceBinding,

Reply via email to