tryElementName = XmlCommon.peekElementName(reader);
+ if (tryElementName.isError()) {
+ return Reporting.Result.failure(tryElementName.getError());
+ }
+
+ switch (tryElementName.getResult()) {
+ case "plainMarker":
+ return readPlainMarkerFromElement(reader);
+ default:
+ return Reporting.Result.failure(new Reporting.Error(
+ "Unexpected element with the name " + tryElementName.getResult()));
+ }
+ }
+
+ /**
+ * Deserialize an instance of class PlainMarker from a sequence of XML elements.
+ *
+ * If {@code isEmptySequence} is set, we should try to deserialize
+ * the instance from an empty sequence. That is, the parent element
+ * was a self-closing element.
+ */
+ private static Reporting.Result readPlainMarkerFromSequence(
+ XMLEventReader reader,
+ boolean isEmptySequence) {
+ return Reporting.Result.success(new PlainMarker());
+ }
+
+ /**
+ * Deserialize an instance of class PlainMarker from an XML element.
+ */
+ private static Reporting.Result extends PlainMarker> readPlainMarkerFromElement(
+ XMLEventReader reader) {
+ return XmlCommon.readNamedElement(
+ reader,
+ "plainMarker",
+ _DeserializeImplementation::readPlainMarkerFromSequence);
+ }
+
/**
* Deserialize an instance of class Something from a sequence of XML elements.
*
@@ -991,6 +1037,52 @@ public static Blossom deserializeBlossom(
});
}
+ /**
+ * Deserialize an instance of IMarker from {@code reader}.
+ *
+ * @param reader Initialized XML reader with reader.peek() set to the element
+ */
+ public static IMarker deserializeIMarker(
+ XMLEventReader reader) {
+
+ _DeserializeImplementation.skipStartDocument(reader);
+ XmlCommon.skipWhitespaceAndComments(reader);
+
+ Reporting.Result extends IMarker> result =
+ _DeserializeImplementation.readIMarkerFromElement(
+ reader);
+
+ return result.onError(error -> {
+ error.prependSegment(new Reporting.NameSegment("imarker"));
+ throw new XmlCommon.DeserializeException(
+ Reporting.generateRelativeXPath(error.getPathSegments()),
+ error.getCause());
+ });
+ }
+
+ /**
+ * Deserialize an instance of PlainMarker from {@code reader}.
+ *
+ * @param reader Initialized XML reader with reader.peek() set to the element
+ */
+ public static PlainMarker deserializePlainMarker(
+ XMLEventReader reader) {
+
+ _DeserializeImplementation.skipStartDocument(reader);
+ XmlCommon.skipWhitespaceAndComments(reader);
+
+ Reporting.Result extends PlainMarker> result =
+ _DeserializeImplementation.readPlainMarkerFromElement(
+ reader);
+
+ return result.onError(error -> {
+ error.prependSegment(new Reporting.NameSegment("plainmarker"));
+ throw new XmlCommon.DeserializeException(
+ Reporting.generateRelativeXPath(error.getPathSegments()),
+ error.getCause());
+ });
+ }
+
/**
* Deserialize an instance of Something from {@code reader}.
*
@@ -1231,6 +1323,24 @@ public void visitBlossom(
_VisitorWithWriter::writeBlossomAsSequence);
}
+ private static void writePlainMarkerAsSequence(
+ IPlainMarker that,
+ XMLStreamWriter writer) {
+ // Intentionally empty.
+ }
+
+ @Override
+ public void visitPlainMarker(
+ IPlainMarker that,
+ XMLStreamWriter writer) {
+ XmlCommon.writeElement(
+ "plainMarker",
+ that,
+ writer,
+ withNamespace,
+ _VisitorWithWriter::writePlainMarkerAsSequence);
+ }
+
private static void writeSomethingAsSequence(
ISomething that,
XMLStreamWriter writer) {
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/CommonJsonization.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/CommonJsonization.java
index f5e0c21d6..2a274083d 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/CommonJsonization.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/CommonJsonization.java
@@ -94,6 +94,32 @@ public static Blossom loadMinimalBlossom() throws IOException {
return Jsonization.Deserialize.deserializeBlossom(node);
} // public static Blossom loadMinimalBlossom
+ public static PlainMarker loadMaximalPlainMarker() throws IOException {
+ final Path path = Paths.get(
+ Common.TEST_DATA_DIR,
+ "Json",
+ "Expected",
+ "PlainMarker",
+ "maximal.json");
+
+ final JsonNode node = CommonJson.readFromFile(path);
+
+ return Jsonization.Deserialize.deserializePlainMarker(node);
+ } // public static PlainMarker loadMaximalPlainMarker
+
+ public static PlainMarker loadMinimalPlainMarker() throws IOException {
+ final Path path = Paths.get(
+ Common.TEST_DATA_DIR,
+ "Json",
+ "Expected",
+ "PlainMarker",
+ "minimal.json");
+
+ final JsonNode node = CommonJson.readFromFile(path);
+
+ return Jsonization.Deserialize.deserializePlainMarker(node);
+ } // public static PlainMarker loadMinimalPlainMarker
+
public static Something loadMaximalSomething() throws IOException {
final Path path = Paths.get(
Common.TEST_DATA_DIR,
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestCopying.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestCopying.java
index 7d2f3146f..c3838587b 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestCopying.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestCopying.java
@@ -63,6 +63,17 @@ public Boolean transformBlossom(IBlossom that, IClass other) {
&& that.getDetails().equals(casted.getDetails()));
}
+ @Override
+ public Boolean transformPlainMarker(IPlainMarker that, IClass other) {
+ if (!(other instanceof PlainMarker)) {
+ return false;
+ }
+
+ PlainMarker casted = (PlainMarker) other;
+
+ return true;
+ }
+
@Override
public Boolean transformSomething(ISomething that, IClass other) {
if (!(other instanceof Something)) {
@@ -119,6 +130,12 @@ private static Boolean BlossomShallowEquals(
&& that.getDetails().equals(other.getDetails()));
}
+ private static Boolean PlainMarkerShallowEquals(
+ PlainMarker that,
+ PlainMarker other) {
+ return true;
+ }
+
private static Boolean SomethingShallowEquals(
Something that,
Something other) {
@@ -147,6 +164,10 @@ private static Boolean BlossomDeepEquals(Blossom that, Blossom other) {
return DeepEqualiserInstance.transform(that, other);
}
+ private static Boolean PlainMarkerDeepEquals(PlainMarker that, PlainMarker other) {
+ return DeepEqualiserInstance.transform(that, other);
+ }
+
private static Boolean SomethingDeepEquals(Something that, Something other) {
return DeepEqualiserInstance.transform(that, other);
}
@@ -215,6 +236,26 @@ public void testBlossomDeepCopy() throws IOException {
"Blossom");
} // public void testBlossomDeepCopy
+ @Test
+ public void testPlainMarkerShallowCopy() throws IOException {
+ final PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+ final PlainMarker instanceCopy = Copying.shallow(instance);
+
+ assertTrue(
+ PlainMarkerShallowEquals(instance, instanceCopy),
+ "PlainMarker");
+ } // public void testPlainMarkerShallowCopy
+
+ @Test
+ public void testPlainMarkerDeepCopy() throws IOException {
+ final PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+ final PlainMarker instanceCopy = Copying.deep(instance);
+
+ assertTrue(
+ PlainMarkerDeepEquals(instance, instanceCopy),
+ "PlainMarker");
+ } // public void testPlainMarkerDeepCopy
+
@Test
public void testSomethingShallowCopy() throws IOException {
final Something instance = CommonJsonization.loadMaximalSomething();
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendAndVisitorThrough.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendAndVisitorThrough.java
index 13792ea3f..29761d829 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendAndVisitorThrough.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendAndVisitorThrough.java
@@ -136,6 +136,27 @@ public void testDescendAgainstVisitorThroughForBlossom() throws IOException {
assertDescendAndVisitorThroughSame(instance);
} // public void testDescendAgainstVisitorThroughForBlossom
+ @Test
+ public void testDescendOfPlainMarker() throws IOException {
+ final PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+
+ compareOrRerecordTrace(
+ instance,
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "Descend",
+ "PlainMarker",
+ "maximal.json.trace"));
+ } // public void testDescendOfPlainMarker
+
+ @Test
+ public void testDescendAgainstVisitorThroughForPlainMarker() throws IOException {
+ PlainMarker instance = (
+ CommonJsonization.loadMaximalPlainMarker());
+
+ assertDescendAndVisitorThroughSame(instance);
+ } // public void testDescendAgainstVisitorThroughForPlainMarker
+
@Test
public void testDescendOfSomething() throws IOException {
final Something instance = CommonJsonization.loadMaximalSomething();
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendOnce.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendOnce.java
index b429bb60c..86085483e 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendOnce.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestDescendOnce.java
@@ -83,6 +83,19 @@ public void testBlossom() throws IOException {
"maximal.json.trace"));
} // public void testBlossom
+ @Test
+ public void testPlainMarker() throws IOException {
+ PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+
+ compareOrRerecordTrace(
+ instance,
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "DescendOnce",
+ "PlainMarker",
+ "maximal.json.trace"));
+ } // public void testPlainMarker
+
@Test
public void testSomething() throws IOException {
Something instance = CommonJsonization.loadMaximalSomething();
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestEnhancing.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestEnhancing.java
index 360c39db7..c6f53075d 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestEnhancing.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestEnhancing.java
@@ -130,6 +130,37 @@ public void testBlossom() throws IOException {
.orElseThrow(() -> new IllegalStateException("Missing max value for wrapped.")));
} // public void testBlossom
+ @Test
+ public void testPlainMarker() throws IOException {
+ final PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+
+ final Enhancer<_Enhancement> enhancer = createEnhancer();
+
+ assert !enhancer.unwrap(instance).isPresent();
+
+ final IClass wrapped = enhancer.wrap(instance);
+ assertNotNull(wrapped);
+
+ final Set idSet = new HashSet<>();
+ idSet.add(enhancer.mustUnwrap(wrapped).someCustomId);
+ wrapped
+ .descend()
+ .forEach(descendant -> idSet.add(enhancer.mustUnwrap(descendant).someCustomId));
+
+ assertFalse(enhancer.unwrap(instance).isPresent());
+ assertNotNull(wrapped);
+ assertEquals(
+ 1L,
+ idSet.stream()
+ .min(Comparator.comparing(Long::valueOf))
+ .orElseThrow(() -> new IllegalStateException("Missing min value for wrapped.")));
+ assertEquals(
+ idSet.size(),
+ idSet.stream()
+ .max(Comparator.comparing(Long::valueOf))
+ .orElseThrow(() -> new IllegalStateException("Missing max value for wrapped.")));
+ } // public void testPlainMarker
+
@Test
public void testSomething() throws IOException {
final Something instance = CommonJsonization.loadMaximalSomething();
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfConcreteClasses.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfConcreteClasses.java
index de7545754..bad030bc2 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfConcreteClasses.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfConcreteClasses.java
@@ -379,6 +379,105 @@ public void testBlossomVerificationFail() throws IOException {
}
} // public void testBlossomVerificationFail
+ @Test
+ public void testPlainMarkerOk() throws IOException {
+ final ObjectMapper objectMapper = new ObjectMapper();
+
+ final Path searchPath = Paths.get(
+ Common.TEST_DATA_DIR,
+ "Json",
+ "Expected",
+ "PlainMarker");
+ final List paths = Common.findPaths(searchPath, ".json");
+
+ for (Path path : paths) {
+ final JsonNode node = objectMapper.readTree(path.toFile());
+ final PlainMarker instance = Jsonization.Deserialize.deserializePlainMarker(node);
+
+ final Iterable errorIter = Verification.verify(instance);
+ final List errors = Common.asList(errorIter);
+ Common.assertNoVerificationErrors(errors, path);
+ }
+ } // public void testPlainMarkerOk
+
+ @Test
+ public void testPlainMarkerDeserializationFromNonObjectFail() throws IOException {
+ final JsonNode node = JsonNodeFactory.instance.textNode("INVALID");
+
+ Jsonization.DeserializeException exception = null;
+ try {
+ final PlainMarker unused = Jsonization.Deserialize.deserializePlainMarker(node);
+ } catch (Jsonization.DeserializeException observedException) {
+ exception = observedException;
+ }
+
+ assert exception != null : "Expected an exception, but got none";
+ assert exception.getMessage().startsWith("Expected a JsonObject, but got ") :
+ "Unexpected exception message: " + exception.getMessage();
+ } // public void testPlainMarkerDeserializationFromNonObjectFail
+
+ @Test
+ public void testPlainMarkerDeserializationFail() throws IOException {
+ for (Path causeDir :
+ Common.findDirs(
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "Json",
+ "Unexpected",
+ "Unserializable"))) {
+ final Path clsDir = causeDir.resolve("PlainMarker");
+
+ if (!Files.exists(clsDir)) {
+ // No examples of PlainMarker for the failure cause.
+ continue;
+ }
+
+ final List paths = Common.findPaths(clsDir, ".json");
+ for (Path path : paths) {
+ final JsonNode node = CommonJson.readFromFile(path);
+
+ Jsonization.DeserializeException exception = null;
+ try {
+ final PlainMarker var = Jsonization.Deserialize.deserializePlainMarker(node);
+ } catch (Jsonization.DeserializeException observedException) {
+ exception = observedException;
+ }
+
+ assertEqualsExpectedOrRerecordDeserializationException(
+ exception, path);
+ }
+ }
+ } // public void testPlainMarkerDeserializationFail
+
+ @Test
+ public void testPlainMarkerVerificationFail() throws IOException {
+ for (Path causeDir :
+ Common.findDirs(
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "Json",
+ "Unexpected",
+ "Invalid"))) {
+ final Path clsDir = causeDir.resolve("PlainMarker");
+
+ if (!Files.exists(clsDir)) {
+ // No examples of PlainMarker for the failure cause.
+ continue;
+ }
+
+ final List paths = Common.findPaths(clsDir, ".json");
+ for (Path path : paths) {
+ final JsonNode node = CommonJson.readFromFile(path);
+
+ final PlainMarker instance = Jsonization.Deserialize.deserializePlainMarker(node);
+
+ final Iterable errorIter = Verification.verify(instance);
+ final List errors = Common.asList(errorIter);
+ Common.assertEqualsExpectedOrRerecordVerificationErrors(errors, path);
+ }
+ }
+ } // public void testPlainMarkerVerificationFail
+
@Test
public void testSomethingOk() throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfInterfaces.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfInterfaces.java
index a713cf90d..71b1ada41 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfInterfaces.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestJsonizationOfInterfaces.java
@@ -145,6 +145,22 @@ public void testRoundTripILeafFromLeaf()
assertEquals(
objectMapper.readTree(jsonObject.toString()), objectMapper.readTree(anotherJsonObject.toString()));
} // void testRoundTripILeafFromLeaf
+
+ @Test
+ public void testRoundTripIMarkerFromPlainMarker()
+ throws IOException, JsonProcessingException {
+ final ObjectMapper objectMapper = new ObjectMapper();
+
+ PlainMarker instance = CommonJsonization.loadMaximalPlainMarker();
+ final JsonNode jsonObject = Jsonization.Serialize.toJsonObject(instance);
+
+ IMarker anotherInstance = Jsonization.Deserialize.deserializeIMarker(
+ jsonObject);
+ final JsonNode anotherJsonObject = Jsonization.Serialize.toJsonObject(anotherInstance);
+
+ assertEquals(
+ objectMapper.readTree(jsonObject.toString()), objectMapper.readTree(anotherJsonObject.toString()));
+ } // void testRoundTripIMarkerFromPlainMarker
} // class TestJsonizationOfInterfaces
// package dummy.tests
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfConcreteClasses.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfConcreteClasses.java
index b00f9be50..c7bed6396 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfConcreteClasses.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfConcreteClasses.java
@@ -486,6 +486,99 @@ public void testBlossomVerificationFail() throws IOException, XMLStreamException
}
} // public void testBlossomVerificationFail
+ @Test
+ public void testPlainMarkerOk() throws IOException, XMLStreamException {
+ final Path searchPath =
+ Paths.get(Common.TEST_DATA_DIR, "Xml", "Expected", "plainMarker");
+ final List paths = Common.findPaths(searchPath, ".xml");
+
+ for (Path path : paths) {
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ final XMLEventReader xmlReader =
+ xmlInputFactory.createXMLEventReader(Files.newInputStream(path));
+
+ final PlainMarker instance =
+ Xmlization.Deserialize.deserializePlainMarker(xmlReader);
+
+ final Iterable errorIter = Verification.verify(instance);
+ final List errors = Common.asList(errorIter);
+ Common.assertNoVerificationErrors(errors, path);
+
+ assertSerializeDeserializeEqualsOriginal(instance, path);
+ }
+ } // public void testPlainMarkerOk
+
+ @Test
+ public void testPlainMarkerDeserializationFail() throws IOException, XMLStreamException {
+ for (
+ Path causeDir :
+ Common.findDirs(
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "Xml",
+ "Unexpected",
+ "Unserializable"))) {
+ final Path clsDir =
+ causeDir.resolve("plainMarker");
+
+ if (!Files.exists(clsDir)) {
+ // No examples of PlainMarker for the failure cause.
+ continue;
+ }
+
+ final List paths = Common.findPaths(clsDir, ".xml");
+ for (Path path : paths) {
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ final XMLEventReader xmlReader =
+ xmlInputFactory.createXMLEventReader(Files.newInputStream(path));
+
+ XmlCommon.DeserializeException exception = null;
+
+ try {
+ Xmlization.Deserialize.deserializePlainMarker(xmlReader);
+ } catch (XmlCommon.DeserializeException observedException) {
+ exception = observedException;
+ }
+
+ assertEqualsExpectedOrRerecordDeserializationException(exception, path);
+ }
+ }
+ } // public void testPlainMarkerDeserializationFail
+
+ @Test
+ public void testPlainMarkerVerificationFail() throws IOException, XMLStreamException {
+ for (
+ Path causeDir :
+ Common.findDirs(
+ Paths.get(
+ Common.TEST_DATA_DIR,
+ "Xml",
+ "Unexpected",
+ "Invalid"))) {
+ final Path clsDir = causeDir.resolve(
+ "plainMarker");
+
+ if (!Files.exists(clsDir)) {
+ // No examples of PlainMarker for the failure cause.
+ continue;
+ }
+
+ final List paths = Common.findPaths(clsDir, ".xml");
+ for (Path path : paths) {
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ final XMLEventReader xmlReader =
+ xmlInputFactory.createXMLEventReader(Files.newInputStream(path));
+
+ final PlainMarker instance =
+ Xmlization.Deserialize.deserializePlainMarker(xmlReader);
+
+ final Iterable errorIter = Verification.verify(instance);
+ final List errors = Common.asList(errorIter);
+ Common.assertEqualsExpectedOrRerecordVerificationErrors(errors, path);
+ }
+ }
+ } // public void testPlainMarkerVerificationFail
+
@Test
public void testSomethingOk() throws IOException, XMLStreamException {
final Path searchPath =
diff --git a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfInterfaces.java b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfInterfaces.java
index 58786c4c2..e93db9603 100644
--- a/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfInterfaces.java
+++ b/dev/test_data/main/java/expected/deep_class_hierarchy/expected_output/src/test/java/TestXmlizationOfInterfaces.java
@@ -272,6 +272,38 @@ public void testRoundTripILeafFromLeaf()
// Compare
assertEquals(outputText, anotherStringOut.toString());
} // void testRoundTripILeafFromLeaf
+
+ @Test
+ public void testRoundTripIMarkerFromPlainMarker()
+ throws IOException, XMLStreamException {
+ // We load from JSON here just to jump-start the round trip.
+ // The round-trip goes then over XML.
+ final IMarker instance =
+ CommonJsonization.loadMaximalPlainMarker();
+
+ // The round-trip starts here.
+ final StringWriter stringOut = new StringWriter();
+ final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
+ final XMLStreamWriter xmlWriter = outputFactory.createXMLStreamWriter(stringOut);
+
+ Xmlization.Serialize.to(instance, xmlWriter);
+ String outputText = stringOut.toString();
+
+ // De-serialize from XML
+ final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ final XMLEventReader xmlReader =
+ xmlInputFactory.createXMLEventReader(new StringReader(outputText));
+ final IMarker anotherInstance =
+ Xmlization.Deserialize.deserializeIMarker(xmlReader);
+
+ // Serialize back to XML
+ final StringWriter anotherStringOut = new StringWriter();
+ final XMLStreamWriter anotherXmlWriter = outputFactory.createXMLStreamWriter(anotherStringOut);
+ Xmlization.Serialize.to(anotherInstance, anotherXmlWriter);
+
+ // Compare
+ assertEquals(outputText, anotherStringOut.toString());
+ } // void testRoundTripIMarkerFromPlainMarker
} // class TestXmlizationOfInterfaces
// package dummy.tests
diff --git a/dev/test_data/main/jsonschema/expected/deep_class_hierarchy/expected_output/schema.json b/dev/test_data/main/jsonschema/expected/deep_class_hierarchy/expected_output/schema.json
index d58fd4d1b..1130c409f 100644
--- a/dev/test_data/main/jsonschema/expected/deep_class_hierarchy/expected_output/schema.json
+++ b/dev/test_data/main/jsonschema/expected/deep_class_hierarchy/expected_output/schema.json
@@ -129,12 +129,24 @@
}
]
},
+ "Marker": {
+ "type": "object",
+ "properties": {
+ "modelType": {
+ "$ref": "#/definitions/ModelType"
+ }
+ },
+ "required": [
+ "modelType"
+ ]
+ },
"ModelType": {
"type": "string",
"enum": [
"Blossom",
"Branch",
- "Leaf"
+ "Leaf",
+ "PlainMarker"
]
},
"Node": {
@@ -165,6 +177,20 @@
}
]
},
+ "PlainMarker": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/Marker"
+ },
+ {
+ "properties": {
+ "modelType": {
+ "const": "PlainMarker"
+ }
+ }
+ }
+ ]
+ },
"Something": {
"type": "object",
"properties": {
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/common_jsonization.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/common_jsonization.py
index 7eec079a9..ebe6c370e 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/common_jsonization.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/common_jsonization.py
@@ -128,6 +128,8 @@ def check_equal(
our_jsonization.container_from_jsonable,
'Leaf':
our_jsonization.leaf_from_jsonable,
+ 'PlainMarker':
+ our_jsonization.plain_marker_from_jsonable,
'Something':
our_jsonization.something_from_jsonable
}
@@ -145,6 +147,8 @@ def check_equal(
our_types.Container,
'Leaf':
our_types.Leaf,
+ 'PlainMarker':
+ our_types.PlainMarker,
'Something':
our_types.Something
}
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_classes_with_descendants.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_classes_with_descendants.py
index 71e396684..714608ce7 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_classes_with_descendants.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_classes_with_descendants.py
@@ -107,6 +107,34 @@ def test_leaf(self) -> None:
self.assertListEqual([], list(map(str, mismatch)))
+ def test_marker(self) -> None:
+ for descendant_model_type in [
+ 'PlainMarker'
+ ]:
+ for path in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Json"
+ / "Expected"
+ / descendant_model_type
+ ).glob("**/*.json")
+ ):
+ with path.open("rt") as fid:
+ original_jsonable = json.load(fid)
+
+ instance = our_jsonization.marker_from_jsonable(
+ original_jsonable
+ )
+
+ another_jsonable = our_jsonization.to_jsonable(instance)
+
+ mismatch = tests.common_jsonization.check_equal(
+ original_jsonable,
+ another_jsonable
+ )
+
+ self.assertListEqual([], list(map(str, mismatch)))
+
if __name__ == "__main__":
unittest.main()
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_concrete_classes.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_concrete_classes.py
index 4956913af..9e29a8430 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_concrete_classes.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_jsonization_of_concrete_classes.py
@@ -94,6 +94,30 @@ def test_blossom(self) -> None:
)
self.assertListEqual([], list(map(str, mismatches)))
+ def test_plain_marker(self) -> None:
+ for path in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Json"
+ / "Expected"
+ / 'PlainMarker'
+ ).glob("**/*.json")
+ ):
+ with path.open("rt") as fid:
+ original_jsonable = json.load(fid)
+
+ instance = our_jsonization.plain_marker_from_jsonable(
+ original_jsonable
+ )
+
+ another_jsonable = our_jsonization.to_jsonable(instance)
+
+ mismatches = tests.common_jsonization.check_equal(
+ original_jsonable,
+ another_jsonable
+ )
+ self.assertListEqual([], list(map(str, mismatches)))
+
def test_something(self) -> None:
for path in sorted(
(
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_verification.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_verification.py
index 6a40cc895..23c4c65eb 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_verification.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_verification.py
@@ -95,6 +95,31 @@ def test_blossom(self) -> None:
)
)
+ def test_plain_marker(self) -> None:
+ for path in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Json"
+ / "Expected"
+ / 'PlainMarker'
+ ).glob("**/*.json")
+ ):
+ with path.open("rt") as fid:
+ jsonable = json.load(fid)
+
+ instance = our_jsonization.plain_marker_from_jsonable(jsonable)
+
+ errors = list(our_verification.verify(instance))
+
+ if len(errors) > 0:
+ self.fail(
+ f"Expected no errors when verifying the instance de-serialized "
+ f"from {path}, but got {len(errors)} error(s):\n"
+ + "\n".join(
+ f"{error.path}: {error.cause}" for error in errors
+ )
+ )
+
def test_something(self) -> None:
for path in sorted(
(
@@ -270,6 +295,47 @@ def test_blossom(self) -> None:
tests.common.record_or_check(expected_path, got)
+ def test_plain_marker(self) -> None:
+ for cause_dir in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Json"
+ / "Unexpected"
+ / "Invalid"
+ ).iterdir()
+ ):
+ for path in sorted(
+ (cause_dir / 'PlainMarker').glob("**/*.json")
+ ):
+ rel_path = path.relative_to(tests.common.TEST_DATA_DIR)
+
+ expected_path = (
+ tests.common.TEST_DATA_DIR
+ / "VerificationError"
+ / rel_path.parent
+ / f"{rel_path.name}.errors"
+ )
+
+ with path.open("rt") as fid:
+ jsonable = json.load(fid)
+
+ instance = our_jsonization.plain_marker_from_jsonable(jsonable)
+
+ errors = list(our_verification.verify(instance))
+
+ if len(errors) == 0:
+ self.fail(
+ f"Expected at least one verification error "
+ f"when verifying the instance de-serialized "
+ f"from {path}, but got none"
+ )
+
+ got = "\n".join(
+ f"{error.path}: {error.cause}" for error in errors
+ ) + "\n"
+
+ tests.common.record_or_check(expected_path, got)
+
def test_something(self) -> None:
for cause_dir in sorted(
(
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_classes_with_descendants.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_classes_with_descendants.py
index d3a3bb2d7..7031aec86 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_classes_with_descendants.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_classes_with_descendants.py
@@ -176,6 +176,56 @@ def test_leaf(self) -> None:
tests.common_xmlization.assert_elements_equal(et_concrete, et_from_str)
# endregion
+ def test_marker(self) -> None:
+ for xml_class_name_of_descendant in [
+ 'plainMarker'
+ ]:
+ for path in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Xml"
+ / "Expected"
+ / xml_class_name_of_descendant
+ ).glob("**/*.xml")
+ ):
+ text = path.read_text(encoding="utf-8")
+ et_concrete = ET.fromstring(text)
+ tests.common_xmlization.remove_redundant_whitespace(et_concrete)
+
+ # region From iterparse
+ iterator = ET.iterparse(source=io.StringIO(text), events=["start", "end"])
+ got_from_iterparse = our_xmlization.marker_from_iterparse(iterator)
+
+ et_from_iterparse = ET.fromstring(our_xmlization.to_str(got_from_iterparse))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_iterparse)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_iterparse)
+ # endregion
+
+ # region From stream
+ got_from_stream = our_xmlization.marker_from_stream(io.StringIO(text))
+ et_from_stream = ET.fromstring(our_xmlization.to_str(got_from_stream))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_stream)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_stream)
+ # endregion
+
+ # region From file
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ path = pathlib.Path(tmp_dir) / "something.xml"
+ path.write_text(text, encoding="utf-8")
+
+ got_from_file = our_xmlization.marker_from_file(path)
+ et_from_file = ET.fromstring(our_xmlization.to_str(got_from_file))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_file)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_file)
+ # endregion
+
+ # region From string
+ got_from_str = our_xmlization.marker_from_str(text)
+ et_from_str = ET.fromstring(our_xmlization.to_str(got_from_str))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_str)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_str)
+ # endregion
+
if __name__ == "__main__":
unittest.main()
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_concrete_classes.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_concrete_classes.py
index 7df34643e..2ae7d9132 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_concrete_classes.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dev/tests/test_xmlization_of_concrete_classes.py
@@ -205,6 +205,66 @@ def test_blossom(self) -> None:
tests.common_xmlization.assert_elements_equal(et_concrete, et_from_str)
# endregion
+ def test_plain_marker(self) -> None:
+ for path in sorted(
+ (
+ tests.common.TEST_DATA_DIR
+ / "Xml"
+ / "Expected"
+ / 'plainMarker'
+ ).glob("**/*.xml")
+ ):
+ text = path.read_text(encoding="utf-8")
+ et_concrete = ET.fromstring(text)
+ tests.common_xmlization.remove_redundant_whitespace(et_concrete)
+
+ # region From iterparse
+ iterator = ET.iterparse(source=io.StringIO(text), events=["start", "end"])
+ got_from_iterparse = (
+ our_xmlization.plain_marker_from_iterparse(iterator)
+ )
+
+ et_from_iterparse = ET.fromstring(our_xmlization.to_str(got_from_iterparse))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_iterparse)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_iterparse)
+ # endregion
+
+ # region From stream
+ got_from_stream = (
+ our_xmlization
+ .plain_marker_from_stream(
+ io.StringIO(text)
+ )
+ )
+ et_from_stream = ET.fromstring(our_xmlization.to_str(got_from_stream))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_stream)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_stream)
+ # endregion
+
+ # region From file
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ path = pathlib.Path(tmp_dir) / "something.xml"
+ path.write_text(text, encoding="utf-8")
+
+ got_from_file = (
+ our_xmlization
+ .plain_marker_from_file(path)
+ )
+ et_from_file = ET.fromstring(our_xmlization.to_str(got_from_file))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_file)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_file)
+ # endregion
+
+ # region From string
+ got_from_str = (
+ our_xmlization
+ .plain_marker_from_str(text)
+ )
+ et_from_str = ET.fromstring(our_xmlization.to_str(got_from_str))
+ tests.common_xmlization.remove_redundant_whitespace(et_from_str)
+ tests.common_xmlization.assert_elements_equal(et_concrete, et_from_str)
+ # endregion
+
def test_something(self) -> None:
for path in sorted(
(
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/jsonization.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/jsonization.py
index e95809063..f5c48a42a 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/jsonization.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/jsonization.py
@@ -598,6 +598,62 @@ def blossom_from_jsonable(
)
+def marker_from_jsonable(
+ jsonable: Jsonable
+) -> our_types.Marker:
+ """
+ Parse an instance of :py:class:`.types.Marker` from the JSON-able
+ structure :paramref:`jsonable`.
+
+ :param jsonable: structure to be parsed
+ :return: Concrete instance of :py:class:`.types.Marker`
+ :raise: :py:class:`DeserializationException` if unexpected :paramref:`jsonable`
+ """
+ return _dispatch_from_jsonable(
+ jsonable,
+ _MARKER_FROM_JSONABLE_DISPATCH,
+ 'Marker'
+ )
+
+
+def plain_marker_from_jsonable(
+ jsonable: Jsonable
+) -> our_types.PlainMarker:
+ """
+ Parse an instance of :py:class:`.types.PlainMarker` from the JSON-able
+ structure :paramref:`jsonable`.
+
+ :param jsonable: structure to be parsed
+ :return: Parsed instance of :py:class:`.types.PlainMarker`
+ :raise: :py:class:`DeserializationException` if unexpected :paramref:`jsonable`
+ """
+ mapping = _as_mapping(jsonable)
+
+ model_type = mapping.get('modelType', None)
+ if model_type != 'PlainMarker':
+ raise DeserializationException(
+ f"Expected modelType to be 'PlainMarker', "
+ f"but got: {model_type!r}"
+ )
+
+ try:
+ for key in mapping:
+ if key == 'modelType':
+ # The model type has already been checked above.
+ pass
+ else:
+ raise DeserializationException(
+ f"Unexpected property: {key}"
+ )
+ except DeserializationException as exception:
+ exception.path._prepend(
+ PropertySegment(mapping, key)
+ )
+ raise
+
+ return our_types.PlainMarker()
+
+
def something_from_jsonable(
jsonable: Jsonable
) -> our_types.Something:
@@ -735,6 +791,16 @@ def container_from_jsonable(
}
+#: De-serialize a concrete instance of
+#: :py:class:`.types.Marker`, by its model type
+_MARKER_FROM_JSONABLE_DISPATCH: Mapping[
+ str,
+ _Parser[our_types.Marker]
+] = {
+ 'PlainMarker': plain_marker_from_jsonable,
+}
+
+
# endregion
@@ -891,6 +957,15 @@ def _blossom_to_jsonable(
return jsonable
+def _plain_marker_to_jsonable(
+ that: our_types.PlainMarker
+) -> MutableMapping[str, MutableJsonable]:
+ """Serialize :paramref:`that` to a JSON-able representation."""
+ jsonable: MutableMapping[str, MutableJsonable] = dict()
+ jsonable['modelType'] = 'PlainMarker'
+ return jsonable
+
+
def _something_to_jsonable(
that: our_types.Something
) -> MutableMapping[str, MutableJsonable]:
@@ -950,6 +1025,9 @@ class _Serializer(
transform_blossom = staticmethod(
_blossom_to_jsonable
)
+ transform_plain_marker = staticmethod(
+ _plain_marker_to_jsonable
+ )
transform_something = staticmethod(
_something_to_jsonable
)
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/types.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/types.py
index 260e8829e..b3971bfce 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/types.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/types.py
@@ -346,6 +346,84 @@ def __init__(
self.details = details
+class Marker(Class):
+ # pylint: disable=missing-class-docstring
+ pass
+
+
+class PlainMarker(Marker):
+ # pylint: disable=missing-class-docstring
+
+ def descend_once(self) -> Iterator[Class]:
+ """
+ Iterate over the instances referenced from this instance.
+
+ We do not recurse into the referenced instance.
+
+ :yield: instances directly referenced from this instance
+ """
+ return self._descend(recurse=False)
+
+ def descend(self) -> Iterator[Class]:
+ """
+ Iterate recursively over the instances referenced from this one.
+
+ :yield: instances recursively referenced from this instance
+ """
+ return self._descend(recurse=True)
+
+ def _descend(self, recurse: bool) -> Iterator[Class]:
+ """
+ Iterate over the instances referenced from this one, and recursively
+ over their descendants if :paramref:`recurse` is set.
+
+ :param recurse: if set, descend recursively into the referenced instances
+ :yield: instances referenced from this instance
+ """
+ # No descendable properties
+ return
+ # For this uncommon return-yield construction, see:
+ # https://stackoverflow.com/questions/13243766/how-to-define-an-empty-generator-function
+ # noinspection PyUnreachableCode
+ yield
+
+ def accept(self, visitor: "AbstractVisitor") -> None:
+ """Dispatch the :paramref:`visitor` on this instance."""
+ visitor.visit_plain_marker(self)
+
+ def accept_with_context(
+ self,
+ visitor: "AbstractVisitorWithContext[ContextT]",
+ context: ContextT
+ ) -> None:
+ """Dispatch the :paramref:`visitor` on this instance in :paramref:`context`."""
+ visitor.visit_plain_marker_with_context(self, context)
+
+ def transform(
+ self,
+ transformer: "AbstractTransformer[T]"
+ ) -> T:
+ """Dispatch the :paramref:`transformer` on this instance."""
+ return transformer.transform_plain_marker(self)
+
+ def transform_with_context(
+ self,
+ transformer: "AbstractTransformerWithContext[ContextT, T]",
+ context: ContextT
+ ) -> T:
+ """
+ Dispatch the :paramref:`transformer` on this instance in :paramref:`context`.
+ """
+ return transformer.transform_plain_marker_with_context(
+ self, context)
+
+ def __init__(self) -> None:
+ """Initialize with the given values."""
+ Marker.__init__(
+ self
+ )
+
+
class Something(Class):
# pylint: disable=missing-class-docstring
@@ -545,6 +623,14 @@ def visit_blossom(
"""Visit :paramref:`that`."""
raise NotImplementedError()
+ @abc.abstractmethod
+ def visit_plain_marker(
+ self,
+ that: PlainMarker
+ ) -> None:
+ """Visit :paramref:`that`."""
+ raise NotImplementedError()
+
@abc.abstractmethod
def visit_something(
self,
@@ -599,6 +685,15 @@ def visit_blossom_with_context(
"""Visit :paramref:`that` in :paramref:`context`."""
raise NotImplementedError()
+ @abc.abstractmethod
+ def visit_plain_marker_with_context(
+ self,
+ that: PlainMarker,
+ context: ContextT
+ ) -> None:
+ """Visit :paramref:`that` in :paramref:`context`."""
+ raise NotImplementedError()
+
@abc.abstractmethod
def visit_something_with_context(
self,
@@ -656,6 +751,14 @@ def visit_blossom(
for another in that.descend_once():
self.visit(another)
+ def visit_plain_marker(
+ self,
+ that: PlainMarker
+ ) -> None:
+ """Visit :paramref:`that`."""
+ for another in that.descend_once():
+ self.visit(another)
+
def visit_something(
self,
that: Something
@@ -717,6 +820,15 @@ def visit_blossom_with_context(
for another in that.descend_once():
self.visit_with_context(another, context)
+ def visit_plain_marker_with_context(
+ self,
+ that: PlainMarker,
+ context: ContextT
+ ) -> None:
+ """Visit :paramref:`that` in :paramref:`context`."""
+ for another in that.descend_once():
+ self.visit_with_context(another, context)
+
def visit_something_with_context(
self,
that: Something,
@@ -769,6 +881,14 @@ def transform_blossom(
"""Transform :paramref:`that`."""
raise NotImplementedError()
+ @abc.abstractmethod
+ def transform_plain_marker(
+ self,
+ that: PlainMarker
+ ) -> T:
+ """Transform :paramref:`that`."""
+ raise NotImplementedError()
+
@abc.abstractmethod
def transform_something(
self,
@@ -825,6 +945,15 @@ def transform_blossom_with_context(
"""Transform :paramref:`that` in :paramref:`context`."""
raise NotImplementedError()
+ @abc.abstractmethod
+ def transform_plain_marker_with_context(
+ self,
+ that: PlainMarker,
+ context: ContextT
+ ) -> T:
+ """Transform :paramref:`that` in :paramref:`context`."""
+ raise NotImplementedError()
+
@abc.abstractmethod
def transform_something_with_context(
self,
@@ -886,6 +1015,13 @@ def transform_blossom(
"""Transform :paramref:`that`."""
return self.default
+ def transform_plain_marker(
+ self,
+ that: PlainMarker
+ ) -> T:
+ """Transform :paramref:`that`."""
+ return self.default
+
def transform_something(
self,
that: Something
@@ -949,6 +1085,14 @@ def transform_blossom_with_context(
"""Transform :paramref:`that` in :paramref:`context`."""
return self.default
+ def transform_plain_marker_with_context(
+ self,
+ that: PlainMarker,
+ context: ContextT
+ ) -> T:
+ """Transform :paramref:`that` in :paramref:`context`."""
+ return self.default
+
def transform_something_with_context(
self,
that: Something,
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/verification.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/verification.py
index 534f54f94..7ad5dc204 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/verification.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/verification.py
@@ -103,6 +103,18 @@ def transform_blossom(
# noinspection PyUnreachableCode
yield
+ # noinspection PyMethodMayBeStatic
+ def transform_plain_marker(
+ self,
+ that: our_types.PlainMarker
+ ) -> Iterator[Error]:
+ # No verification has been defined for PlainMarker.
+ return
+ # For this uncommon return-yield construction, see:
+ # https://stackoverflow.com/questions/13243766/how-to-define-an-empty-generator-function
+ # noinspection PyUnreachableCode
+ yield
+
# noinspection PyMethodMayBeStatic
def transform_something(
self,
diff --git a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/xmlization.py b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/xmlization.py
index e5f394c58..d75621154 100644
--- a/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/xmlization.py
+++ b/dev/test_data/main/python/expected/deep_class_hierarchy/expected_output/dummy/xmlization.py
@@ -875,6 +875,364 @@ def blossom_from_str(
)
+def marker_from_iterparse(
+ iterator: Iterator[Tuple[str, Element]]
+) -> our_types.Marker:
+ """
+ Read an instance of :py:class:`.types.Marker` from
+ the :paramref:`iterator`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import xml.etree.ElementTree as ET
+
+ import dummy.xmlization as our_xmlization
+
+ path = pathlib.Path(...)
+ with path.open("rt") as fid:
+ iterator = ET.iterparse(
+ source=fid,
+ events=['start', 'end']
+ )
+ instance = our_xmlization.marker_from_iterparse(
+ iterator
+ )
+
+ # Do something with the ``instance``
+
+ :param iterator:
+ Input stream of ``(event, element)`` coming from
+ :py:func:`xml.etree.ElementTree.iterparse` with the argument
+ ``events=["start", "end"]``
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.Marker` read from
+ :paramref:`iterator`
+ """
+ return _read_instance_from_iterparse(
+ iterator,
+ _read_marker_as_element,
+ 'Marker'
+ )
+
+
+def marker_from_stream(
+ stream: TextIO,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.Marker:
+ """
+ Read an instance of :py:class:`.types.Marker` from
+ the :paramref:`stream`.
+
+ Example usage:
+
+ .. code-block::
+
+ import dummy.xmlization as our_xmlization
+
+ with open_some_stream_over_network(...) as stream:
+ instance = our_xmlization.marker_from_stream(
+ stream
+ )
+
+ # Do something with the ``instance``
+
+ :param stream:
+ representing an instance of
+ :py:class:`.types.Marker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.Marker` read from
+ :paramref:`stream`
+ """
+ iterator = has_iterparse.iterparse(
+ stream,
+ ['start', 'end']
+ )
+ return marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
+def marker_from_file(
+ path: PathLike,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.Marker:
+ """
+ Read an instance of :py:class:`.types.Marker` from
+ the :paramref:`path`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import dummy.xmlization as our_xmlization
+
+ path = pathlib.Path(...)
+ instance = our_xmlization.marker_from_file(
+ path
+ )
+
+ # Do something with the ``instance``
+
+ :param path:
+ to the file representing an instance of
+ :py:class:`.types.Marker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.Marker` read from
+ :paramref:`path`
+ """
+ with open(os.fspath(path), "rt", encoding='utf-8') as fid:
+ iterator = has_iterparse.iterparse(
+ fid,
+ ['start', 'end']
+ )
+ return marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
+def marker_from_str(
+ text: str,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.Marker:
+ """
+ Read an instance of :py:class:`.types.Marker` from
+ the :paramref:`text`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import dummy.xmlization as our_xmlization
+
+ text = "<...>..."
+ instance = our_xmlization.marker_from_str(
+ text
+ )
+
+ # Do something with the ``instance``
+
+ :param text:
+ representing an instance of
+ :py:class:`.types.Marker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.Marker` read from
+ :paramref:`text`
+ """
+ iterator = has_iterparse.iterparse(
+ io.StringIO(text),
+ ['start', 'end']
+ )
+ return marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
+def plain_marker_from_iterparse(
+ iterator: Iterator[Tuple[str, Element]]
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker` from
+ the :paramref:`iterator`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import xml.etree.ElementTree as ET
+
+ import dummy.xmlization as our_xmlization
+
+ path = pathlib.Path(...)
+ with path.open("rt") as fid:
+ iterator = ET.iterparse(
+ source=fid,
+ events=['start', 'end']
+ )
+ instance = our_xmlization.plain_marker_from_iterparse(
+ iterator
+ )
+
+ # Do something with the ``instance``
+
+ :param iterator:
+ Input stream of ``(event, element)`` coming from
+ :py:func:`xml.etree.ElementTree.iterparse` with the argument
+ ``events=["start", "end"]``
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.PlainMarker` read from
+ :paramref:`iterator`
+ """
+ return _read_instance_from_iterparse(
+ iterator,
+ _read_plain_marker_as_element,
+ 'PlainMarker'
+ )
+
+
+def plain_marker_from_stream(
+ stream: TextIO,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker` from
+ the :paramref:`stream`.
+
+ Example usage:
+
+ .. code-block::
+
+ import dummy.xmlization as our_xmlization
+
+ with open_some_stream_over_network(...) as stream:
+ instance = our_xmlization.plain_marker_from_stream(
+ stream
+ )
+
+ # Do something with the ``instance``
+
+ :param stream:
+ representing an instance of
+ :py:class:`.types.PlainMarker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.PlainMarker` read from
+ :paramref:`stream`
+ """
+ iterator = has_iterparse.iterparse(
+ stream,
+ ['start', 'end']
+ )
+ return plain_marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
+def plain_marker_from_file(
+ path: PathLike,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker` from
+ the :paramref:`path`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import dummy.xmlization as our_xmlization
+
+ path = pathlib.Path(...)
+ instance = our_xmlization.plain_marker_from_file(
+ path
+ )
+
+ # Do something with the ``instance``
+
+ :param path:
+ to the file representing an instance of
+ :py:class:`.types.PlainMarker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.PlainMarker` read from
+ :paramref:`path`
+ """
+ with open(os.fspath(path), "rt", encoding='utf-8') as fid:
+ iterator = has_iterparse.iterparse(
+ fid,
+ ['start', 'end']
+ )
+ return plain_marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
+def plain_marker_from_str(
+ text: str,
+ has_iterparse: HasIterparse = xml.etree.ElementTree
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker` from
+ the :paramref:`text`.
+
+ Example usage:
+
+ .. code-block::
+
+ import pathlib
+ import dummy.xmlization as our_xmlization
+
+ text = "<...>..."
+ instance = our_xmlization.plain_marker_from_str(
+ text
+ )
+
+ # Do something with the ``instance``
+
+ :param text:
+ representing an instance of
+ :py:class:`.types.PlainMarker` in XML
+ :param has_iterparse:
+ Module containing ``iterparse`` function.
+
+ Default is to use :py:mod:`xml.etree.ElementTree` from the standard
+ library. If you have to deal with malicious input, consider using
+ a library such as `defusedxml.ElementTree`_.
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return:
+ Instance of :py:class:`.types.PlainMarker` read from
+ :paramref:`text`
+ """
+ iterator = has_iterparse.iterparse(
+ io.StringIO(text),
+ ['start', 'end']
+ )
+ return plain_marker_from_iterparse(
+ _with_elements_cleared_after_yield(iterator)
+ )
+
+
def something_from_iterparse(
iterator: Iterator[Tuple[str, Element]]
) -> our_types.Something:
@@ -2037,6 +2395,82 @@ def _read_blossom_as_element(
)
+def _read_marker_as_element(
+ element: Element,
+ iterator: Iterator[Tuple[str, Element]]
+) -> our_types.Marker:
+ """
+ Read an instance of :py:class:`.types.Marker` from
+ :paramref:`iterator`, including the end element.
+
+ :param element: start element
+ :param iterator:
+ Input stream of ``(event, element)`` coming from
+ :py:func:`xml.etree.ElementTree.iterparse` with the argument
+ ``events=["start", "end"]``
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return: parsed instance
+ """
+ return _read_dispatched(
+ element,
+ iterator,
+ _DISPATCH_FOR_MARKER,
+ "a concrete instance of 'Marker'"
+ )
+
+
+def _read_plain_marker_as_sequence(
+ element: Element,
+ iterator: Iterator[Tuple[str, Element]]
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker`
+ as a sequence of XML-encoded properties.
+
+ The end element corresponding to the :paramref:`element` will be
+ read as well.
+
+ :param element: start element, parent of the sequence
+ :param iterator:
+ Input stream of ``(event, element)`` coming from
+ :py:func:`xml.etree.ElementTree.iterparse` with the argument
+ ``events=["start", "end"]``
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return: parsed instance
+ """
+ _read_properties(
+ element,
+ iterator,
+ _READERS_FOR_PLAIN_MARKER
+ )
+
+ return our_types.PlainMarker()
+
+
+def _read_plain_marker_as_element(
+ element: Element,
+ iterator: Iterator[Tuple[str, Element]]
+) -> our_types.PlainMarker:
+ """
+ Read an instance of :py:class:`.types.PlainMarker` from
+ :paramref:`iterator`, including the end element.
+
+ :param element: start element
+ :param iterator:
+ Input stream of ``(event, element)`` coming from
+ :py:func:`xml.etree.ElementTree.iterparse` with the argument
+ ``events=["start", "end"]``
+ :raise: :py:class:`DeserializationException` if unexpected input
+ :return: parsed instance
+ """
+ return _read_named_element(
+ element,
+ iterator,
+ 'plainMarker',
+ _read_plain_marker_as_sequence
+ )
+
+
def _read_something_as_sequence(
element: Element,
iterator: Iterator[Tuple[str, Element]]
@@ -2251,6 +2685,22 @@ def _read_as_element(
}
+#: Dispatch XML class names to read-as-sequence functions
+#: corresponding to concrete descendants of Marker
+_DISPATCH_FOR_MARKER: Mapping[
+ str,
+ Callable[
+ [
+ Element,
+ Iterator[Tuple[str, Element]]
+ ],
+ our_types.Marker
+ ]
+] = {
+ 'plainMarker': _read_plain_marker_as_sequence,
+}
+
+
#: Dispatch XML class names to read-as-sequence functions
#: corresponding to the concrete classes
_GENERAL_DISPATCH: Mapping[
@@ -2266,6 +2716,7 @@ def _read_as_element(
'branch': _read_branch_as_sequence,
'leaf': _read_leaf_as_sequence,
'blossom': _read_blossom_as_sequence,
+ 'plainMarker': _read_plain_marker_as_sequence,
'something': _read_something_as_sequence,
'container': _read_container_as_sequence,
}
@@ -2307,6 +2758,15 @@ def _read_as_element(
}
+#: Read the content of a property of
+#: :py:class:`.types.PlainMarker`, by the XML name of the property
+_READERS_FOR_PLAIN_MARKER: Mapping[
+ str,
+ _ContentReader[Any]
+] = {
+}
+
+
#: Read the content of a property of
#: :py:class:`.types.Something`, by the XML name of the property
_READERS_FOR_SOMETHING: Mapping[
@@ -2605,6 +3065,32 @@ def _write_blossom_as_element(
_attribute_to_property(exception, prop_name)
+def _write_plain_marker_as_element(
+ name: str,
+ prop_name: Optional[str],
+ that: our_types.PlainMarker,
+ serializer: '_Serializer'
+) -> None:
+ """
+ Write :paramref:`that` enclosed in the :paramref:`name` element.
+
+ There are no properties specified for this class, so the element is always
+ empty.
+
+ :param name: of the element tag. Expected to contain no XML special characters.
+ :param prop_name:
+ name of the property, as spelled in Python, whose value is written, or
+ ``None`` if the access to the value is recorded by an enclosing writer
+ :param that: instance to be serialized
+ :param serializer: to write to
+ :raise: :py:class:`SerializationException` if the value could not be written
+ """
+ try:
+ serializer.writer.write_empty_element(name)
+ except Exception as exception:
+ _attribute_to_property(exception, prop_name)
+
+
def _write_something_as_element(
name: str,
prop_name: Optional[str],
@@ -2726,6 +3212,20 @@ def visit_blossom(
"""
_write_blossom_as_element('blossom', None, that, self)
+ def visit_plain_marker(
+ self,
+ that: our_types.PlainMarker
+ ) -> None:
+ """
+ Serialize :paramref:`that` to :py:attr:`~stream` as an XML element.
+
+ The enclosing XML element designates the class of the instance, where its
+ children correspond to the properties of the instance.
+
+ :param that: instance to be serialized
+ """
+ _write_plain_marker_as_element('plainMarker', None, that, self)
+
def visit_something(
self,
that: our_types.Something
diff --git a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/jsonization.ts b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/jsonization.ts
index 1288cd597..f10829d16 100644
--- a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/jsonization.ts
+++ b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/jsonization.ts
@@ -1065,6 +1065,121 @@ export function blossomFromJsonable(
return parsePropertiesOfBlossom(jsonObject);
}
+/**
+ * Parse `jsonable` as an instance
+ * of {@link types!IMarker}.
+ *
+ * @param jsonable - to be parsed
+ * @returns parsed instance, or error if `jsonable` is invalid
+ */
+export function markerFromJsonable(
+ jsonable: JsonValue
+): OurCommon.Either<
+ OurTypes.IMarker,
+ DeserializationError
+> {
+ const objectError = checkIsJsonObject(jsonable);
+ if (objectError !== null) {
+ return new OurCommon.Either<
+ OurTypes.IMarker,
+ DeserializationError
+ >(
+ null,
+ objectError
+ );
+ }
+ const jsonObject = jsonable;
+
+ const modelTypeOrError = extractModelType(jsonObject);
+ if (modelTypeOrError.error !== null) {
+ return new OurCommon.Either<
+ OurTypes.IMarker,
+ DeserializationError
+ >(
+ null,
+ modelTypeOrError.error
+ );
+ }
+
+ const modelType = modelTypeOrError.mustValue();
+
+ switch (modelType) {
+ case "PlainMarker":
+ return parsePropertiesOfPlainMarker(jsonObject);
+
+ default:
+ return newDeserializationError(
+ `Unexpected model type for IMarker: ${modelType}`
+ );
+ }
+}
+
+/**
+ * Parse the properties of an instance
+ * of {@link types!PlainMarker} from `jsonObject`.
+ *
+ * The `modelType` is expected to have been already verified by the caller,
+ * and is therefore skipped here.
+ *
+ * @param jsonObject - JSON object to be parsed
+ * @returns parsed instance of {@link types!PlainMarker},
+ * or an error if any
+ */
+function parsePropertiesOfPlainMarker(
+ jsonObject: JsonObject
+): OurCommon.Either<
+ OurTypes.PlainMarker,
+ DeserializationError
+> {
+ return new OurCommon.Either<
+ OurTypes.PlainMarker,
+ DeserializationError
+ >(
+ new OurTypes.PlainMarker(),
+ null
+ );
+}
+
+/**
+ * Parse an instance of {@link types!PlainMarker} from the JSON-able
+ * structure `jsonable`.
+ *
+ * @param jsonable - structure to be parsed
+ * @returns parsed instance of {@link types!PlainMarker},
+ * or an error if any
+ */
+export function plainMarkerFromJsonable(
+ jsonable: JsonValue
+): OurCommon.Either<
+ OurTypes.PlainMarker,
+ DeserializationError
+> {
+ const objectError = checkIsJsonObject(jsonable);
+ if (objectError !== null) {
+ return new OurCommon.Either<
+ OurTypes.PlainMarker,
+ DeserializationError
+ >(
+ null,
+ objectError
+ );
+ }
+ const jsonObject = jsonable;
+
+ const modelTypeError = checkModelType(jsonObject, "PlainMarker");
+ if (modelTypeError !== null) {
+ return new OurCommon.Either<
+ OurTypes.PlainMarker,
+ DeserializationError
+ >(
+ null,
+ modelTypeError
+ );
+ }
+
+ return parsePropertiesOfPlainMarker(jsonObject);
+}
+
/**
* Parse the properties of an instance
* of {@link types!Something} from `jsonObject`.
@@ -1493,6 +1608,22 @@ function serializeBlossom(
return jsonable;
}
+/**
+ * Serialize `that` to a JSON-able representation.
+ *
+ * @param that - instance to be serialized
+ * @returns JSON-able representation
+ */
+function serializePlainMarker(
+ that: OurTypes.PlainMarker
+): JsonObject {
+ const jsonable: JsonObject = {};
+
+ jsonable["modelType"] = "PlainMarker";
+
+ return jsonable;
+}
+
/**
* Serialize `that` to a JSON-able representation.
*
@@ -1577,6 +1708,12 @@ class Serializer extends OurTypes.AbstractTransformer {
return serializeBlossom(that);
}
+ transformPlainMarker(
+ that: OurTypes.PlainMarker
+ ): JsonObject {
+ return serializePlainMarker(that);
+ }
+
transformSomething(
that: OurTypes.Something
): JsonObject {
diff --git a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/stringification.ts b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/stringification.ts
index 1db7ae760..2cb1d1cb1 100644
--- a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/stringification.ts
+++ b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/stringification.ts
@@ -20,6 +20,10 @@ const MODEL_TYPE_FROM_STRING = new Map([
"Blossom",
OurTypes.ModelType.Blossom
],
+ [
+ "PlainMarker",
+ OurTypes.ModelType.PlainMarker
+ ],
[
"Something",
OurTypes.ModelType.Something
@@ -50,6 +54,7 @@ const MODEL_TYPE_TO_STRING: readonly string[] = [
"Branch",
"Leaf",
"Blossom",
+ "PlainMarker",
"Something",
"Container"
];
diff --git a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/types.ts b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/types.ts
index 67392ff71..1450605e6 100644
--- a/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/types.ts
+++ b/dev/test_data/main/typescript/expected/deep_class_hierarchy/expected_output/src/types.ts
@@ -8,8 +8,9 @@ export enum ModelType {
Branch = 0,
Leaf = 1,
Blossom = 2,
- Something = 3,
- Container = 4
+ PlainMarker = 3,
+ Something = 4,
+ Container = 5
}
/**
@@ -29,8 +30,9 @@ export function *overModelType (
yield 0; // Branch
yield 1; // Leaf
yield 2; // Blossom
- yield 3; // Something
- yield 4; // Container
+ yield 3; // PlainMarker
+ yield 4; // Something
+ yield 5; // Container
}
/**
@@ -417,6 +419,97 @@ export class Blossom
}
}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface IMarker extends Class {
+ // Intentionally empty.
+}
+
+export class PlainMarker
+ extends Class
+ implements IMarker {
+ /**
+ * Indicate the runtime model type of the instance.
+ */
+ modelType(): ModelType {
+ // NOTE (mristin):
+ // We yield numbers instead of literals to avoid name lookups on platforms
+ // which do not provide JIT compilation of hot paths.
+ return 3; // PlainMarker
+ }
+
+ /**
+ * Iterate over the instances referenced from this instance.
+ *
+ * We do not recurse into the referenced instances.
+ *
+ * @returns Iterator over the referenced instances
+ */
+ *descendOnce(): IterableIterator {
+ // No descendable properties
+ }
+
+ /**
+ * Iterate recursively over the instances referenced from this instance.
+ *
+ * @returns Iterator over the referenced instances
+ */
+ *descend(): IterableIterator {
+ // No descendable properties
+ }
+
+ /**
+ * Dispatch `visitor` on this instance.
+ *
+ * @param visitor - to visit this instance
+ */
+ accept(visitor: AbstractVisitor): void {
+ visitor.visitPlainMarker(this);
+ }
+
+ /**
+ * Dispatch `visitor` with `context` on this instance.
+ *
+ * @param visitor - to visit this instance
+ * @param context - to be passed along to the dispatched visitor method
+ * @typeParam ContextT - type of the context
+ */
+ acceptWithContext(
+ visitor: AbstractVisitorWithContext,
+ context: ContextT
+ ) {
+ visitor.visitPlainMarkerWithContext(this, context);
+ }
+
+ /**
+ * Dispatch the `transformer` on this instance.
+ *
+ * @param transformer - to transform this instance
+ * @returns transformation of this instance
+ * @paramType T - type of the transformation result
+ */
+ transform(transformer: AbstractTransformer): T {
+ return transformer.transformPlainMarker(this);
+ }
+
+ /**
+ * Dispatch the `transformer` on this instance in `context`.
+ *
+ * @param transformer - to transform this instance
+ * @param context - to be passed along to the `transformer`
+ * @returns transformation of this instance
+ * @paramType T - type of the transformation result
+ * @paramType ContextT - type of the transformation context
+ */
+ transformWithContext(
+ transformer: AbstractTransformerWithContext,
+ context: ContextT
+ ): T {
+ return transformer.transformPlainMarkerWithContext(
+ this, context
+ );
+ }
+}
+
export class Something extends Class {
/**
* Indicate the runtime model type of the instance.
@@ -425,7 +518,7 @@ export class Something extends Class {
// NOTE (mristin):
// We yield numbers instead of literals to avoid name lookups on platforms
// which do not provide JIT compilation of hot paths.
- return 3; // Something
+ return 4; // Something
}
someChoice: INode;
@@ -543,7 +636,7 @@ export class Container extends Class {
// NOTE (mristin):
// We yield numbers instead of literals to avoid name lookups on platforms
// which do not provide JIT compilation of hot paths.
- return 4; // Container
+ return