def genAttributeGroup()

in daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala [189:307]


  def genAttributeGroup(ag: Node): String = {
    // val name = stripSuffix("AG", attr(ag, "name"))
    val name =
      attr(
        ag,
        "name"
      ).get // let's try leaving AG suffix in place so we can distinguish generated type mixins from AG mixins.
    if (excludeType(name)) return ""
    val subAgs = ag \ "attributeGroup"
    val subRefAgs = subAgs.filter(ag => attr(ag, "ref") != None)
    // val subNames = subRefAgs.map(ag => stripSuffix("AG", stripDFDLPrefix(attr(ag, "ref"))))
    val subNames =
      subRefAgs.map(ag => stripDFDLPrefix(attr(ag, "ref").get)) // leave AG suffix on.
    assert(subAgs.length == subRefAgs.length) // "nested attributeGroup was not a reference"
    val attribs = ag \ "attribute"
    //
    // for each attribute that is an Enum type, we want to use a Mixin of that type
    //
    val attribsNoDafRefs = attribs.flatMap { attrNode =>
      val rawRef = attr(attrNode, "ref")
      if (rawRef.isDefined) {
        // this is referencing a Daffodil Extension, go find that attribute

        if (rawRef.get.startsWith("daf:")) {
          // ignore daf prefix and the dfdlx:Layer attribute group. These are
          // duplicated in dfdlx for backwards compatability, so this ignores
          // the duplicate.
          None
        } else {
          val refWithoutPrefix = stripPrefix("dfdlx:", rawRef.get)
          val dafAttrNode = (PropertyGenerator.daffodilExtensionsXML \ "attribute").find {
            node =>
              attr(node, "name").get == refWithoutPrefix
          }.get
          Some(dafAttrNode)
        }
      } else {
        Some(attrNode)
      }
    }

    val nonExcludedAttribs = attribsNoDafRefs.filter { attrNode =>
      val rawName = attr(attrNode, "name").get
      !excludeAttribute(rawName)
    }

    val (enumAttributeList, nonEnumAttributeList) = nonExcludedAttribs.partition { attrNode =>
      {
        val qualifiedTypeName = attr(attrNode, "type").get
        val rawName = attr(attrNode, "name").get
        val rawNameWithoutTextPrefix = stripPrefix("text", rawName)
        val nameIsInTypeName =
          qualifiedTypeName.toLowerCase.contains(rawNameWithoutTextPrefix.toLowerCase)
        val endsInEnum = qualifiedTypeName.endsWith("Enum")
        val res = endsInEnum && nameIsInTypeName
        res
      }
    }

    val enumList = enumAttributeList.map { attrNode =>
      {
        val qualifiedTypeName = attr(attrNode, "type").get
        val enumName = stripSuffix("Enum", stripDFDLPrefix(qualifiedTypeName))
        enumName
      }
    }

    //
    // for other attributes, we generate a member
    //
    val attrNamesTypes = nonEnumAttributeList.flatMap(attrNode => {
      val rawName = attr(attrNode, "name").get
      //
      // exclude certain attribute names that aren't format properties
      // We don't want properties for these.
      val notFormatProperties =
        List("ref", "type", "name", "test", "defaultValue", "message", "baseFormat")
      val notScopedFormatProperties = List(
        "inputValueCalc",
        "outputValueCalc",
        "hiddenGroupRef"
      ) // do these by-hand since they are not scoped.
      val excludedBecauseDoneByHand =
        List(
          "runtimeProperties",
          "separatorPolicy",
          "separatorSuppressionPolicy",
          "textOutputMinLength",
          "textStandardExponentCharacter",
          "textStandardExponentRep",
          "textStandardInfinityRep",
          "textStandardNaNRep",
          "textStandardZeroRep",
          "nilValue",
          "textStringPadCharacter",
          "textNumberPadCharacter",
          "textBooleanPadCharacter",
          "textCalendarPadCharacter"
        )
      val exclusions =
        notFormatProperties ++ notScopedFormatProperties ++ excludedBecauseDoneByHand
      if (exclusions.contains(rawName)) {
        Nil
      } else {
        val name = if (isScalaKeyword(rawName)) rawName + "_" else rawName
        val qualifiedTypeName = attr(attrNode, "type").get
        // we still might have some enums here, because we exclude enums above that
        // aren't matching the name of the attribute. (e.g., if we have an attribute which has type YesNo, then
        // that will show up as a YesNoEnum here.
        val typeName = stripSuffix("Enum", stripDFDLPrefix(qualifiedTypeName))
        // val typeName = stripDFDLPrefix(qualifiedTypeName) // leave suffix on.
        List((name, typeName))
      }
    })

    val res = generatePropertyGroup(name, attrNamesTypes, subNames, enumList)
    val block = comment(ag) + res + sep
    block
  }