mbeckerle commented on code in PR #1187:
URL: https://github.com/apache/daffodil/pull/1187#discussion_r1534359871


##########
daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/layers/api/Layer.java:
##########
@@ -0,0 +1,182 @@
+/*
+ * 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.runtime1.layers.api;
+
+import org.apache.daffodil.runtime1.layers.LayerRuntime;
+import org.apache.daffodil.runtime1.layers.LayerUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This is the primary API class for writing layers.
+ * <p/>
+ * All layers are derived from this class, and must have no-args default 
constructors.
+ * <p/>
+ * Derived classes will be dynamically loaded by Java's SPI system.
+ * The names of concrete classes derived from Layer are listed in a 
resources/META-INF/services file
+ * so that they can be found and dynamically loaded.
+ * <p/>
+ * The SPI creates an instance the class by calling a default (no-arg) 
constructor, which should be
+ * the only constructor.
+ * <p/>
+ * Instances of derived layer classes can be stateful. They are private to 
threads, and each time a layer
+ * is encountered during parse/unparse, an instance is created for that 
situation.
+ * <p/>
+ * Layer instances should not share mutable state (such as via singleton 
objects)
+ * <p/>
+ * The rest of the Layer class implements the
+ * layer decode/encode logic, which is done as part of deriving one's Layer 
class from the
+ * Layer base class.
+ * <p/>
+ * About variables: Layer logic may read and write DFDL variables.
+ * <p/>
+ * Every DFDL Variable in the layer's targetNamespace is used either at the 
start of the
+ * layer algorithm as a parameter to the layer or at the end of the layer 
algorithm it is
+ * assigned as a return value (such as a checksum) from the layer.
+ * <p/>
+ * Variables being written must be undefined, since variables in DFDL are 
single-assignment.
+ * <p/>
+ * Variables being read must be defined before being read by the layer, and 
this is true for both
+ * parsing and unparsing. When unparsing, variables being read cannot be 
forward-referencing to parts
+ * of the DFDL infoset that have not yet been unparsed.
+ * <p/>
+ * A layer that wants to read parameters declares special setter named 
'setLayerVariableParameters'
+ * which has args such that each has a name and type that match a corresponding
+ * dfdl:defineVariable in the layer's namespace.
+ * <p/>
+ * A layer that wants to return a value after the layer algorithm completes 
defines a special recognizable
+ * getter method. The name of the getter is formed from prefixing the DFDL 
variable name with the string
+ * 'getLayerVariableResult_'. The return type of the getter must match the 
type of the variable.
+ * <p/>
+ * For example, a result value getter for a DFDL variable named 'checksum' of 
type xs:unsignedShort would be:
+ * <pre>
+ *      int getLayerVariableResult_checksum() {
+ *          // returns the value created by the checksum algorithm.
+ *      }
+ * </pre>
+ * <p/>

Review Comment:
   I am coming around to making any unhandled exception fatal. 
   
   So this is only about thrown instances of Exception class, and only for 
Parsing. 
   
   The argument in favor of unhandled Exceptions being always fatal, is simply 
the conservative engineering thing. By leaving things fatal, we can always add 
a feature in the future which makes one of those fatal behaviors non-fatal, and 
no working schema would be broken by this. But the opposite is not true. If we 
handle exceptions and convert them to PE, then we can't take it back and make 
them fatal without breaking working schemas. 
   
   Another argument in favor of unhandled exceptions being fatal is that a 
layer author really DOES have to think about exception handling, because many 
RuntimeExceptions, like NPE, want to be converted into processing errors. So 
doing this conversion to processing error for Exception, but not 
RuntimeException is a mixed message to the API user. 
   
   For example, what underlying library can a layer call that we would be 
confident would *never* throw an NPE regardless of what gibberish it is being 
asked to parse? I claim people will almost always want to catch NPE and convert 
that to a processing error so that it can be backtracked. You would have to do 
lots of fuzz testing of the layer to convince me that the underlying library 
won't NPE ever.  
   
   A fatal exception is of course a very bad thing when parsing because it 
takes away the freedom of the schema author to design the schema to backtrack 
and keep going. A schema author is not going to have the source code of the 
layer (likely) so they can't fix this or even work around it. 
   
   Any exception (or runtime exception) which could be thrown due to bad data 
being encountered by the layer wants to be caught and become a processing 
error.  So the argument to NOT try to automate this for the layer author is 
that there's no stable design point.  Exception vs. RuntimeException isn't a 
good split because lots of RuntimeExceptions could result from bad data. Heck 
bad data could cause a stack overflow and one *might* want to catch even that 
and convert it to a PE. 
   
   



-- 
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.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to