mbeckerle commented on a change in pull request #343: Daffodil 2302 fixes
external variables API difficulties
URL: https://github.com/apache/incubator-daffodil/pull/343#discussion_r401172445
##########
File path:
daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
##########
@@ -73,190 +73,169 @@ object ForParser extends ParserOrUnparser
object ForUnparser extends ParserOrUnparser
object BothParserAndUnparser extends ParserOrUnparser
-final class ProcessorFactory(val sset: SchemaSet)
- extends SchemaComponentImpl(<pf/>, sset)
- with DFDL.ProcessorFactory
- with HavingRootSpec {
-
- lazy val (generateParser, generateUnparser) = {
- val (context, policy) = tunable.parseUnparsePolicy match {
- case ParseUnparsePolicyTunable.FromRoot => (Some(rootElem),
rootElem.rootParseUnparsePolicy)
- case ParseUnparsePolicyTunable.ParseOnly => (None,
ParseUnparsePolicy.ParseOnly)
- case ParseUnparsePolicyTunable.UnparseOnly => (None,
ParseUnparsePolicy.UnparseOnly)
- case ParseUnparsePolicyTunable.Both => (None, ParseUnparsePolicy.Both)
- }
- rootElem.checkParseUnparsePolicyCompatibility(context, policy)
- policy match {
- case ParseUnparsePolicy.Both => (true, true)
- case ParseUnparsePolicy.ParseOnly => (true, false)
- case ParseUnparsePolicy.UnparseOnly => (false, true)
- }
+final class ProcessorFactory private(
+ private var optRootSpec: Option[RootSpec],
+ /*
+ * compilerExternalVarSettings supports the deprecated API
+ * where external variable settings can be supplied to the compiler
+ * instance.
+ *
+ * The non-deprecated API is to deal with external variable settings
+ * on the data processor instance. This is passed here so that
+ * the PF can propagate it to the DP.
+ */
+ var compilerExternalVarSettings: Queue[Binding],
+ schemaSource: DaffodilSchemaSource,
+ val validateDFDLSchemas: Boolean,
+ checkAllTopLevel: Boolean,
+ tunables: DaffodilTunables,
+ optSchemaSet: Option[SchemaSet])
+ extends DFDL.ProcessorFactory {
+
+ def this(optRootName: Option[String],
+ optRootNamespace: Option[String],
+ compilerExternalVarSettings: Queue[Binding],
+ schemaSource: DaffodilSchemaSource,
+ validateDFDLSchemas: Boolean,
+ checkAllTopLevel: Boolean,
+ tunables: DaffodilTunables) =
+ this(
+ RootSpec.makeRootSpec(optRootName, optRootNamespace), // compute
root-spec object
+ compilerExternalVarSettings, schemaSource, validateDFDLSchemas,
checkAllTopLevel, tunables, None)
+
+ private def copy(
+ optRootSpec: Option[RootSpec] = optRootSpec,
+ compilerExternalVarSettings: Queue[Binding] =
compilerExternalVarSettings): ProcessorFactory =
+ new ProcessorFactory(optRootSpec, compilerExternalVarSettings,
schemaSource, validateDFDLSchemas, checkAllTopLevel, tunables, Some(sset))
+
+ lazy val sset: SchemaSet =
+ optSchemaSet.getOrElse(
+ new SchemaSet(optRootSpec, schemaSource, validateDFDLSchemas,
checkAllTopLevel, tunables,
+ compilerExternalVarSettings))
+
+ def elementBaseInstanceCount = sset.elementBaseInstanceCount
+
+ def diagnostics = sset.diagnostics
+ def getDiagnostics = diagnostics
+
+ override def onPath(xpath: String) = sset.onPath(xpath)
+
+ override def isError = sset.isError
+
+ @deprecated("Use arguments to Compiler.compileSource or compileFile.",
"Since 2.6.0")
+ override def setDistinguishedRootNode(name: String, namespace: String): Unit
= {
+ Assert.usage(name ne null)
+ optRootSpec = RootSpec.makeRootSpec(Option(name), Option(namespace))
}
- lazy val parser = LV('parser) {
- val par = if (generateParser) rootElem.document.parser else new
NotParsableParser(rootElem.erd)
- Processor.initialize(par)
- par
- }.value
-
- lazy val unparser = LV('unparser) {
- val unp = if (generateUnparser) rootElem.document.unparser else new
NotUnparsableUnparser(rootElem.erd)
- Processor.initialize(unp)
- unp
- }.value
-
- lazy val rootElem = sset.root
+ def withDistinguishedRootNode(name: String, namespace: String) :
ProcessorFactory = {
+ Assert.usage(name ne null)
+ copy(optRootSpec = RootSpec.makeRootSpec(Option(name), Option(namespace)))
+ }
+}
- private lazy val checkUnusedProperties = LV('hasUnusedProperties) {
- rootElem.checkUnusedProperties
- }.value
+class InvalidParserException(msg: String, cause: Throwable = null) extends
Exception(msg, cause)
- //
- // breaking this into these lines causes the order things are
- // evaluated in to be more rational than if pure demand-driven
- // lazy evaluation was followed.
- //
- // We want pretty much nothing to be done by the data processor
- //
- requiredEvaluationsAlways(sset)
- requiredEvaluationsAlways(rootElem)
- requiredEvaluationsAlways(parser)
- requiredEvaluationsAlways(unparser)
- requiredEvaluationsAlways(rootElem.runtimeData)
-
- override def isError = {
- ExecutionMode.usingCompilerMode {
- OOLAG.keepGoing(true) {
- val valid = sset.isValid
- if (valid) {
- // no point in going forward with more
- // checks if the schema isn't valid
- // The code base is written assuming valid
- // schema input. It's just going to hit
- // assertion failures and such if we
- // try to compile invalid schemas.
- val requiredErr = super.isError
- val ssetErr = sset.isError
- val hasErrors = requiredErr || ssetErr
- if (!hasErrors) {
- // only check for unused properties if there are no errors
- checkUnusedProperties
- }
- hasErrors
- } else true
- }
- }
- }
+class Compiler private (var validateDFDLSchemas: Boolean,
+ var tunables : DaffodilTunables,
+ /*
+ * Supports deprecated feature of establishing external vars on the compiler
object.
+ * These are just saved and passed to the processor factory which
incorporates them into
+ * the variable map of the data processor.
+ *
+ * This argument can be removed once this deprecated feature is removed.
+ */
+ private var externalDFDLVariables: Queue[Binding],
+ private var checkAllTopLevel : Boolean,
+ private var optRootName: Option[String],
+ private var optRootNamespace: Option[String])
+ extends DFDL.Compiler
+ with Logging {
- override def diagnostics = sset.diagnostics
-
- def onPath(xpath: String): DFDL.DataProcessor = {
- ExecutionMode.usingCompilerMode {
- Assert.usage(!isError)
- if (xpath != "/") rootElem.notYetImplemented("""Path must be "/". Other
path support is not yet implemented.""")
- val rootERD = rootElem.elementRuntimeData
- rootElem.schemaDefinitionUnless(
- rootERD.outputValueCalcExpr.isEmpty,
- "The root element cannot have the dfdl:outputValueCalc property.")
- val validationMode = ValidationMode.Off
- val variables: VariableMap =
rootElem.schemaDocument.schemaSet.variableMap
- val p = if (!rootElem.isError) parser else null
- val u = if (!rootElem.isError) unparser else null
- val ssrd = new SchemaSetRuntimeData(
- p,
- u,
- this.diagnostics,
- rootERD,
- variables,
- validationMode,
- sset.typeCalcMap)
- if (rootElem.numComponents > rootElem.numUniqueComponents)
- log(LogLevel.Info, "Compiler: component counts: unique %s, actual %s.",
- rootElem.numUniqueComponents, rootElem.numComponents)
- val dataProc = new DataProcessor(ssrd, tunable)
- if (dataProc.isError) {
- // NO longer printing anything here. Callers must do this.
- // val diags = dataProc.getDiagnostics
- // log(LogLevel.Error,"Compilation (DataProcessor) reports %s
compile errors/warnings.", diags.length)
- // diags.foreach { diag => log(LogLevel.Error, diag.toString())
}
- } else {
- log(LogLevel.Compile, "Parser = %s.", ssrd.parser.toString)
- //log(LogLevel.Error, "Unparser = %s.", ssrd.unparser.toString)
- log(LogLevel.Compile, "Compilation (DataProcesor) completed with no
errors.")
- }
- dataProc
- }
- }
-}
+ private def this(validateDFDLSchemas: Boolean = true) =
this(validateDFDLSchemas, DaffodilTunables(), Queue.empty, true, None, None)
-/**
- * Both Compiler and ProcessorFactory share this same API call.
- */
-trait HavingRootSpec extends Logging {
- var rootSpec: Option[RootSpec] = None
+ private def copy(validateDFDLSchemas: Boolean = validateDFDLSchemas,
+ tunables : DaffodilTunables = tunables,
+ externalDFDLVariables: Queue[Binding] = externalDFDLVariables,
+ checkAllTopLevel : Boolean = checkAllTopLevel,
+ optRootName: Option[String] = optRootName,
+ optRootNamespace: Option[String] = optRootNamespace) =
+ new Compiler(validateDFDLSchemas, tunables, externalDFDLVariables,
checkAllTopLevel, optRootName, optRootNamespace)
+ @deprecated("Pass argument to compileSource, or compileFile.", "Since 2.6.0")
def setDistinguishedRootNode(name: String, namespace: String): Unit = {
- val ns =
- if (namespace != null) Some(NS(namespace))
- else None
- rootSpec = Some(RootSpec(ns, name))
- // log(Info("%s setDistinguishedRootNode to %s",
Misc.getNameFromClass(this), rootSpec))
- //
- // null means we search for the namespace
- // Must be only one answer.
- //
-
+ Assert.usage(name ne null)
+ optRootName = Option(name)
+ optRootNamespace = Option(namespace)
}
-}
-class InvalidParserException(msg: String, cause: Throwable = null) extends
Exception(msg, cause)
-class Compiler(var validateDFDLSchemas: Boolean = true)
- extends DFDL.Compiler
- with Logging
- with HavingRootSpec {
+ def withDistinguishedRootNode(name: String, namespace: String) : Compiler = {
+ Assert.usage(name ne null)
+ copy(optRootName = Option(name), optRootNamespace = Option(namespace))
+ }
Review comment:
I have updated everything now to deprecate all setters in JAPI/SAPI, and
TDML processor.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services