You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mb...@apache.org on 2018/11/30 21:36:49 UTC

[incubator-daffodil] 01/02: Fixed infinite loop due to not gathering the error reliably.

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

mbeckerle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git

commit 92429a0fc26673d1df362916862729c03a9c9a0a
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Wed Nov 28 21:49:53 2018 -0500

    Fixed infinite loop due to not gathering the error reliably.
    
    This error situation was causing an infinite loop before. No longer
    does.
    
    The test is badElementFormProperty2.
    
    Problem is that a regular scala lazy val x = expression
    If the expression throws, this lazy val will be re-evaluated over and
    over each time it is requested.
    
    That's why we have the LV system. This insures such values are attempted
    exactly once, and if they throw, the fact that they threw is remembered,
    and they're not attempted again.
    
    To reduce overhead we've taken out a bunch of the LVs. But this results
    in compiler errors that ripple. When parts of the compiler can't be LVs
    because they are methods with parameters, it's important to CALL such
    methods from something that IS an LV so that if an error is thrown, it's
    not
    repeatedly thrown.
    
    So a number of LVs have been put back in. Especially on things that
    involve recursive descent or traversal of the DSOM objects or
    corresponding XML.
    
    This also fixes some other minor bugs which were being masked. E.g., a
    test for hiddenGroupRef where the ref is empty string. I also renamed
    this
    test since it was poorly named.
    
    DAFFODIL-2202
---
 .../daffodil/dsom/AnnotatedSchemaComponent.scala   |  7 +-
 .../daffodil/dsom/DFDLFormatAnnotation.scala       | 19 ++---
 .../org/apache/daffodil/dsom/DFDLProperty.scala    |  2 +-
 .../apache/daffodil/dsom/DFDLStatementMixin.scala  | 12 +++
 .../org/apache/daffodil/dsom/ElementBase.scala     |  6 +-
 .../scala/org/apache/daffodil/dsom/GroupDef.scala  | 10 +--
 .../scala/org/apache/daffodil/dsom/GroupRef.scala  | 16 ++--
 .../org/apache/daffodil/dsom/ModelGroup.scala      | 89 +++++++++++++---------
 .../org/apache/daffodil/dsom/SequenceGroup.scala   |  3 +-
 .../daffodil/grammar/SequenceGrammarMixin.scala    | 11 +--
 .../section07/property_syntax/PropertySyntax.tdml  | 13 ++++
 .../property_syntax/property_syntax.dfdl.xsd       | 16 ++++
 .../section14/sequence_groups/SequenceGroup.tdml   | 15 ++--
 .../sequence_groups/TestSequenceGroupsDebug.scala  |  3 -
 .../property_syntax/TestPropertySyntaxNew.scala    |  3 +
 .../sequence_groups/TestSequenceGroups.scala       |  4 +-
 16 files changed, 149 insertions(+), 80 deletions(-)

diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
index 46ed982..0641c46 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
@@ -289,7 +289,7 @@ trait AnnotatedMixin { self: AnnotatedSchemaComponent =>
    * The DFDL annotations on the component, as objects
    * that are subtypes of DFDLAnnotation.
    */
-  final lazy val annotationObjs = {
+  final lazy val annotationObjs = LV('annotationObjs) {
     val objs = dfdlAppInfos.flatMap { dai =>
       {
         val children = dai.child
@@ -302,7 +302,7 @@ trait AnnotatedMixin { self: AnnotatedSchemaComponent =>
       }
     }
     objs
-  }
+  }.value
 
   /**
    * Here we establish an invariant which is that every annotatable schema component has, definitely, has an
@@ -317,6 +317,9 @@ trait AnnotatedMixin { self: AnnotatedSchemaComponent =>
    * is imposed. There *is* a formatAnnotation.
    */
   protected def emptyFormatFactory: DFDLFormatAnnotation
+
+  final lazy val formatAnnotationExpectedName = emptyFormatFactory.xml.asInstanceOf[scala.xml.Elem].label
+
   protected def isMyFormatAnnotation(a: DFDLAnnotation): Boolean
 
   final lazy val formatAnnotation = LV('formatAnnotation) {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
index f0f78f6..303b1ca 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
@@ -145,7 +145,7 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
   //    seq
   //  }
 
-  private lazy val shortFormProperties: Set[PropItem] = {
+  private lazy val shortFormProperties: Set[PropItem] = LV[Set[PropItem]]('shortFormProperties) {
     // shortForm properties should be prefixed by dfdl
     // Remove the dfdl prefix from the attributes so that they
     // can be properly combined later.
@@ -159,9 +159,9 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
     val kvPairsButNotRef = kvPairs.filterNot { _._1 == "ref" } // dfdl:ref is NOT a property
     val pairs = kvPairsButNotRef.map { case (k, v) => (k, (v, annotatedSC)).asInstanceOf[PropItem] }
     pairs.toSet
-  }
+  }.value
 
-  private lazy val longFormProperties: Set[PropItem] = {
+  private lazy val longFormProperties: Set[PropItem] = LV[Set[PropItem]]('longFormProperties) {
     // longForm Properties are not prefixed by dfdl
     val dfdlAttrs = dfdlAttributes(xml).asAttrMap
     schemaDefinitionUnless(dfdlAttrs.isEmpty, "long form properties are not prefixed by dfdl:")
@@ -181,7 +181,7 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
     val dfdlAndDafAttribs = unqualifiedAttribs ++ dafAttrMap
     val res = dfdlAndDafAttribs.map { case (k, v) => (k, (v, this.asInstanceOf[LookupLocation])) }.toSet
     res
-  }
+  }.value
 
   private lazy val elementFormPropertyAnnotations = {
     val props = xml \\ "property"
@@ -191,9 +191,9 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
     res
   }
 
-  private lazy val elementFormProperties: Set[PropItem] = {
+  private lazy val elementFormProperties: Set[PropItem] = LV[Set[PropItem]]('elementFormProperties) {
     elementFormPropertyAnnotations.map { p => (p.name, (p.value, p)) }.toSet
-  }
+  }.value
 
   /**
    * 'locallyConflicting' means conflicting between the short form and long form and
@@ -212,9 +212,10 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
 
   private lazy val hasConflictingPropertyError = locallyConflictingProperties.size != 0
 
-  private lazy val combinedJustThisOneProperties: PropMap = {
+  private lazy val combinedJustThisOneProperties: PropMap = LV('combinedJustThisOneOproperties) {
     // We need this error to occur immediately! Didn't seem to be checked otherwise.
-    schemaDefinitionUnless(!hasConflictingPropertyError,
+    schemaDefinitionUnless(
+      !hasConflictingPropertyError,
       "Short, long, and element form properties overlap: %s at %s",
       locallyConflictingProperties.mkString(", "),
       this.locationDescription)
@@ -222,7 +223,7 @@ abstract class DFDLFormatAnnotation(nodeArg: Node, annotatedSCArg: AnnotatedSche
     val jtoSet = shortFormProperties.union(longFormProperties).union(elementFormProperties)
     val jto = jtoSet.toMap
     jto
-  }
+  }.value
 
   /**
    * Just this one, as in the short, long, and element form properties, on just this
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLProperty.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLProperty.scala
index 129ebe5..e2eeb23 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLProperty.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLProperty.scala
@@ -39,7 +39,7 @@ final class DFDLProperty(xmlArg: Node, formatAnnotation: DFDLFormatAnnotation)
   // TODO: if we grab the value from here, then any qnames inside that value
   // have to be resolved by THIS Object
   lazy val value = {
-    lazy val values: Option[NodeSeq] = xml match {
+    val values: Option[NodeSeq] = xml match {
       case <dfdl:property/> => None
       case <daf:property/> => None
       case <dfdl:property>{ valueNodes @ _* }</dfdl:property> => Some(valueNodes)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
index c58c1ff..676c6f3 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
@@ -112,10 +112,22 @@ trait ProvidesDFDLStatementMixin extends ThrowsSDE with HasTermCheck { self: Ann
       //
       case <dfdl:property>{ _* }</dfdl:property> =>
         SDE("A dfdl:property annotation element is not allowed without a surrounding dfdl:format, dfdl:element, etc. ")
+      case e: scala.xml.Elem if mismatchedFormatAnnotation(e) =>
+        SDE("DFDL annotation type 'dfdl:%s' invalid. Expected 'dfdl:%s'.", e.label, self.formatAnnotationExpectedName)
       case _ => SDE("Invalid DFDL annotation found: %s", node)
     }
   }
 
+  private def mismatchedFormatAnnotation(e: scala.xml.Elem): Boolean = {
+    (e.label, self) match {
+      case ("element", _: ElementBase) => false
+      case ("choice", _: ChoiceTermBase) => false
+      case ("sequence", _: SequenceTermBase) => false
+      case ("simpleType", _: SimpleTypeBase) => false
+      case _ => true
+    }
+  }
+
   /**
    * Validation won't check whether these are validly in place on a DFDL schema, so
    * we allow any annotated object to have them, and then we can do checking on this list
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
index c968603..e2687e1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
@@ -479,7 +479,7 @@ trait ElementBase
   }.value
 
   protected def computeElementRuntimeData(): ElementRuntimeData = {
-    
+
     lazy val childrenERDs: Seq[ElementRuntimeData] =
       elementChildren.map { _.elementRuntimeData }
 
@@ -551,14 +551,14 @@ trait ElementBase
    *
    * Include both represented and non-represented elements.
    */
-  final lazy val elementChildren: Seq[ElementBase] = {
+  final lazy val elementChildren: Seq[ElementBase] = LV('elementChildren) {
     this.typeDef match {
       case ct: ComplexTypeBase => {
         ct.group.elementChildren
       }
       case _ => Nil
     }
-  }
+  }.value
 
   final lazy val elementChildrenCompileInfo =
     elementChildren.map {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
index 7ed1a60..0aef247 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
@@ -66,21 +66,22 @@ trait GroupDefLike
 
   def xmlChildren: Seq[Node]
 
+  private lazy val goodXmlChildren = LV('goodXMLChildren) { xmlChildren.flatMap { removeNonInteresting(_) } }.value
+
   /** Returns the group members that are elements or model groups. */
-  final lazy val groupMembers : Seq[Term] = {
+  final lazy val groupMembers: Seq[Term] = LV('groupMembers) {
     //
     // So we have to flatMap, so that we can tolerate annotation objects (like documentation objects).
     // and our ModelGroup factory has to return Nil for annotations and Text nodes.
     //
-    val goodXmlChildren = LV('goodXMLChildren) { xmlChildren.flatMap { removeNonInteresting(_) } }.value
     val positions = List.range(1, goodXmlChildren.length + 1) // range is exclusive on 2nd arg. So +1.
     val pairs = goodXmlChildren zip positions
     pairs.flatMap {
       case (n, i) =>
         TermFactory(n, this, i)
     }
-  }
-  
+  }.value
+
   /**
    * XML is full of uninteresting text nodes. We just want the element children, not all children.
    */
@@ -143,4 +144,3 @@ final class GlobalChoiceGroupDef(defXMLArg: Node, choiceXML: Node, schemaDocumen
   with ChoiceDefMixin {
 
 }
-
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
index 0bf0766..f889e85 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
@@ -32,7 +32,9 @@ trait GroupRef { self: ModelGroup =>
 
   final override lazy val optReferredToComponent = Some(referredToComponent)
 
-  final override lazy val groupMembers = groupDef.groupMembers
+  final override lazy val groupMembers = LV('groupMembers) {
+    groupDef.groupMembers
+  }.value
 
   override protected def annotationFactory(node: Node): Option[DFDLAnnotation] = {
     node match {
@@ -62,17 +64,18 @@ final class GroupRefFactory(refXMLArg: Node, val refLexicalParent: SchemaCompone
 
   final def qname = this.refQName
 
-  lazy val groupRef = {
+  lazy val groupRef = LV('groupRef) {
     val gdefFactory = parent.schemaSet.getGlobalGroupDef(qname).getOrElse {
       SDE("Referenced group definition not found: %s", this.ref)
     }
     val (gref, _) = gdefFactory.forGroupRef(refXMLArg, refLexicalParent, position, isHidden)
     gref
-  }
+  }.value
 
 }
 
-final class SequenceGroupRef(globalGroupDef: => GlobalSequenceGroupDef,
+final class SequenceGroupRef(
+  globalGroupDef: => GlobalSequenceGroupDef,
   refXML: Node,
   refLexicalParent: SchemaComponent,
   positionArg: Int,
@@ -92,11 +95,12 @@ final class SequenceGroupRef(globalGroupDef: => GlobalSequenceGroupDef,
 
   override def hiddenGroupRefOption = nf
 
-  override lazy val groupDef = globalGroupDef
+  override lazy val groupDef = LV('groupDef) { globalGroupDef }.value
 
 }
 
-final class ChoiceGroupRef(globalGroupDef: => GlobalChoiceGroupDef,
+final class ChoiceGroupRef(
+  globalGroupDef: => GlobalChoiceGroupDef,
   refXML: Node,
   refLexicalParent: SchemaComponent,
   positionArg: Int,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
index 2c9e855..ece2326 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
@@ -46,41 +46,51 @@ object ModelGroupFactory {
    * flatmap it to get a collection of model groups. Nil for non-model groups, non-Nil for the model group
    * object. There should be only one non-Nil.
    */
-  def apply(child: Node, parent: SchemaComponent, position: Int, isHidden: Boolean): List[ModelGroup] = {
-    val childList: List[ModelGroup] = child match {
-      case <sequence>{ _* }</sequence> => {
-        val seq = new Sequence(child, parent, position)
-        if (seq.hiddenGroupRefOption.isDefined) {
-          //
-          // construct the group ref XML, then recursively process that,
-          // but set flag so it will be hidden.
-          //
-          val hgrXML = seq.hiddenGroupRefXML
-          ModelGroupFactory(hgrXML, parent, position, true)
-        } else {
-          List(seq)
+  def apply(child: Node, parent: SchemaComponent, position: Int, isHidden: Boolean,
+    nodesAlreadyTrying: Set[Node] = Set()): List[ModelGroup] = {
+    if (nodesAlreadyTrying.contains(child)) {
+      //
+      // We are chasing our tail. Circular reference among named model groups/terms.
+      //
+      parent.schemaDefinitionError("Model group circular definitions. Group references, or hidden group references form a loop.")
+    } else {
+      val moreNodesAlreadyTrying = nodesAlreadyTrying + child
+
+      val childList: List[ModelGroup] = child match {
+        case <sequence>{ _* }</sequence> => {
+          val seq = new Sequence(child, parent, position)
+          if (seq.hiddenGroupRefOption.isDefined) {
+            //
+            // construct the group ref XML, then recursively process that,
+            // but set flag so it will be hidden.
+            //
+            val hgrXML = seq.hiddenGroupRefXML
+            ModelGroupFactory(hgrXML, parent, position, true, moreNodesAlreadyTrying)
+          } else {
+            List(seq)
+          }
         }
-      }
-      case <choice>{ _* }</choice> => List(new Choice(child, parent, position))
-      case <group>{ _* }</group> => {
-        val pos = parent match {
-          case ct: ComplexTypeBase => 1
-          case mg: ModelGroup => position
-          case gd: GlobalGroupDef => position
+        case <choice>{ _* }</choice> => List(new Choice(child, parent, position))
+        case <group>{ _* }</group> => {
+          val pos = parent match {
+            case ct: ComplexTypeBase => 1
+            case mg: ModelGroup => position
+            case gd: GlobalGroupDef => position
+          }
+          val isH = isHidden || parent.isHidden
+          val groupRefFactory = new GroupRefFactory(child, parent, pos, isH)
+          val groupRefInstance = groupRefFactory.groupRef
+          List(groupRefInstance.asModelGroup)
+        }
+        case <annotation>{ _* }</annotation> => Nil
+        case textNode: Text => Nil
+        case _: Comment => Nil
+        case _ => {
+          parent.SDE("Unrecognized construct: %s", child)
         }
-        val isH = isHidden || parent.isHidden
-        val groupRefFactory = new GroupRefFactory(child, parent, pos, isH)
-        val groupRefInstance = groupRefFactory.groupRef
-        List(groupRefInstance.asModelGroup)
-      }
-      case <annotation>{ _* }</annotation> => Nil
-      case textNode: Text => Nil
-      case _: Comment => Nil
-      case _ => {
-        parent.SDE("Unrecognized construct: %s", child)
       }
+      childList
     }
-    childList
   }
 
 }
@@ -98,7 +108,7 @@ object TermFactory {
    * remove all the parts of the schema that are not relevant.
    *
    */
-  def apply(child: Node, parent: GroupDefLike, position: Int) = {
+  def apply(child: Node, parent: GroupDefLike, position: Int, nodesAlreadyTrying: Set[Node] = Set()) = {
     val childList: List[Term] = child match {
       case <element>{ _* }</element> => {
         val refProp = child.attribute("ref").map { _.text }
@@ -114,7 +124,7 @@ object TermFactory {
       }
       case <annotation>{ _* }</annotation> => Nil
       case textNode: Text => Nil
-      case _ => ModelGroupFactory(child, parent, position, false)
+      case _ => ModelGroupFactory(child, parent, position, false, nodesAlreadyTrying)
     }
     childList
   }
@@ -174,11 +184,16 @@ abstract class ModelGroup
     }
   }
 
-  final lazy val elementChildren: Seq[ElementBase] =
-    groupMembers.flatMap {
-      case eb: ElementBase => Seq(eb)
-      case gb: ModelGroup => gb.elementChildren
+  final lazy val elementChildren: Seq[ElementBase] = LV('elementChildren) {
+    val gms = groupMembers
+    val echls = gms.flatMap { gm =>
+      gm match {
+        case eb: ElementBase => Seq(eb)
+        case gb: ModelGroup => gb.elementChildren
+      }
     }
+    echls
+  }.value
 
   final override lazy val runtimeData: RuntimeData = modelGroupRuntimeData
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
index 795ebdb..b21bc31 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
@@ -295,8 +295,9 @@ trait SequenceDefMixin
   // attribute, not a format property in the usual sense.
   // So we retrieve it by this lower-level mechanism which only combines short and long form.
   //
-  final lazy val hiddenGroupRefOption =
+  final lazy val hiddenGroupRefOption = LV('hiddenGroupRefOption) {
     findPropertyOptionThisComponentOnly("hiddenGroupRef")
+  }.value
 
 }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
index 093c2ad..ebf4716 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
@@ -46,10 +46,12 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
     LayeredSequence(this, new ScalarOrderedSequenceChild(this, term, 1)) // We use 1-based indexing for children.
   }
 
-  private lazy val seqChildren = (groupMembers zip Stream.from(1)).map {
-    case (gm, i) =>
-      sequenceChild(gm, i)
-  }
+  private lazy val seqChildren = LV('seqChildren) {
+    (groupMembers zip Stream.from(1)).map {
+      case (gm, i) =>
+        sequenceChild(gm, i)
+    }
+  }.value
 
   private lazy val orderedSequence = {
     val res = new OrderedSequence(this, seqChildren)
@@ -156,4 +158,3 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
     delimMTA ~ SequenceSeparator(this)
   }
 }
-
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/PropertySyntax.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/PropertySyntax.tdml
index 131f41f..b34dab7 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/PropertySyntax.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/PropertySyntax.tdml
@@ -271,5 +271,18 @@
       <tdml:error>badElementFormProperty</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
+  
+    <tdml:parserTestCase name="badElementFormProperty2" root="badElementFormProperty2"
+    model="property_syntax.dfdl.xsd" description="wrong annotation element.">
+    <tdml:document/>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>DFDL annotation type</tdml:error>
+      <tdml:error>dfdl:sequence</tdml:error>
+      <tdml:error>expected</tdml:error>
+      <tdml:error>dfdl:element</tdml:error>
+      <tdml:error>badElementFormProperty2</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
 
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/property_syntax.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/property_syntax.dfdl.xsd
index e604a09..a05a245 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/property_syntax.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section07/property_syntax/property_syntax.dfdl.xsd
@@ -74,4 +74,20 @@
            </xs:appinfo>
         </xs:annotation> 
       </xs:element>
+      
+      <xs:element name="badElementFormProperty2" type="xs:int">
+        <xs:annotation>
+          <xs:documentation><![CDATA[ 
+            Example of a User mistake. They forgot that element form property
+            syntax must be contained within a format element that matches the
+            annotated object. I.e., dfdl:sequence on an xs:sequence.
+            This was causing DAFFODIL-2202 bug. 
+          ]]></xs:documentation> 
+          <xs:appinfo source="http://www.ogf.org/dfdl/" > 
+             <dfdl:sequence>
+               <dfdl:property name="representation">text</dfdl:property>
+             </dfdl:sequence>
+           </xs:appinfo>
+        </xs:annotation> 
+      </xs:element>
 </xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
index a1b1a17..11aa024 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
@@ -271,7 +271,7 @@
     </xs:element>
   </tdml:defineSchema>
   
-  <tdml:defineSchema name="hiddenGroupEmpty">
+  <tdml:defineSchema name="hiddenGroupRefEmptyString">
     <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" />
 
@@ -286,18 +286,19 @@
   </tdml:defineSchema>
   
   <!--
-    Test name: hiddenGroupEmpty
-       Schema: hiddenGroupEmpty
+    Test name: hiddenGroupRefEmptyString
+       Schema: hiddenGroupRefEmptyString
       Purpose: This test demonstrates that hidden group references cannot be the empty string.
   -->
   
-  <tdml:parserTestCase name="hiddenGroupEmpty" root="e"
-    model="hiddenGroup3" description="Section 14 - Hidden Elements DFDL-14-037R.">
+  <tdml:parserTestCase name="hiddenGroupRefEmptyString" root="e"
+    model="hiddenGroupRefEmptyString" description="Section 14 - Hidden Elements DFDL-14-037R.">
     <tdml:document>
       <tdml:documentPart type="text"><![CDATA[42,2]]></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>QName</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -530,6 +531,7 @@
     </tdml:document>
     <tdml:errors> 
       <tdml:error>Schema Definition Error</tdml:error> 
+      <tdml:error>circular</tdml:error>
     </tdml:errors> 
  </tdml:parserTestCase>
 
@@ -1000,6 +1002,7 @@ more ignored input
 
 	<tdml:defineSchema name="nestedGroupRefs">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited"
           occursCountKind='parsed'/>
 
@@ -1105,7 +1108,7 @@ A,B,C|D,E,F|G,H,I]]></tdml:document>
 
 	<tdml:defineSchema name="nestedGroupRefs2">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
-    <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" 
+        <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" 
           occursCountKind='parsed'/>
 
 		<xs:element name="root">
diff --git a/daffodil-test/src/test/scala-debug/org/apache/daffodil/section14/sequence_groups/TestSequenceGroupsDebug.scala b/daffodil-test/src/test/scala-debug/org/apache/daffodil/section14/sequence_groups/TestSequenceGroupsDebug.scala
index 671580a..2c52cd2 100644
--- a/daffodil-test/src/test/scala-debug/org/apache/daffodil/section14/sequence_groups/TestSequenceGroupsDebug.scala
+++ b/daffodil-test/src/test/scala-debug/org/apache/daffodil/section14/sequence_groups/TestSequenceGroupsDebug.scala
@@ -42,9 +42,6 @@ class TestSequenceGroupsDebug {
   //DFDL-284
   @Test def test_hiddenGroupLoop() { runner_02.runOneTest("hiddenGroupLoop") }
 
-  //DFDL-598
-  @Test def test_hiddenGroupEmpty() { runner_02.runOneTest("hiddenGroupEmpty") }
-
   @Test def test_emptySequenceSDE() { runner_02.runOneTest("emptySequenceSDE") }
 
 }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section07/property_syntax/TestPropertySyntaxNew.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section07/property_syntax/TestPropertySyntaxNew.scala
index 767d742..ab2fd80 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section07/property_syntax/TestPropertySyntaxNew.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section07/property_syntax/TestPropertySyntaxNew.scala
@@ -39,4 +39,7 @@ class TestPropertySyntax2 {
   // JIRA DFDL-1722
   @Test def test_badElementFormProperty() { runner.runOneTest("badElementFormProperty") }
 
+  // DAFFODIL-2202
+  @Test def test_badElementFormProperty2() { runner.runOneTest("badElementFormProperty2") }
+
 }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala
index 2c4565e..2c4040f 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestSequenceGroups.scala
@@ -79,8 +79,8 @@ class TestSequenceGroups {
   //DFDL-284
   // @Test def test_hiddenGroupLoop() { runner_02.runOneTest("hiddenGroupLoop") }
 
-  //DFDL-598
-  // @Test def test_hiddenGroupEmpty() { runner_02.runOneTest("hiddenGroupEmpty") }
+  //DFDL-598(related to, but this test does not say this is fixed)
+  @Test def test_hiddenGroupRefEmptyString() { runner_02.runOneTest("hiddenGroupRefEmptyString") }
 
   @Test def test_AC000() { runner_02.runOneTest("AC000") }
   @Test def test_AD000() { runner_02.runOneTest("AD000") }