use of org.osate.annexsupport.AnnexResolver in project osate2 by osate.
the class AnnexParserAgent method processAnnexSection.
/**
* Common functionality for processing either a {@link DefaultAnnexLibrary} or a {@link DefaultAnnexSubclause}.
* Processing involves parsing the text, attaching the resulting {@link AnnexLibrary} or {@link AnnexSubclause} to
* the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}, setting the modes for the resulting
* {@link AnnexSubclause}, and either running the resolver or the linking service, depending upon which one if
* available. If the resolver produces errors, then the {@link AnnexLibrary} or {@link AnnexSubclause} will be
* detached from the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}. All error, warning, and info
* messages that are produced from the parser, resolver, or linker will be passed along to
* {@code diagnosticsConsumer}.
*
* @param <A> Type of the resulting annex section. Expected to be {@link AnnexLibrary} or {@link AnnexSubclause}.
* @param <D> Type of the default annex section. Expected to be {@link DefaultAnnexLibrary} or
* {@link DefaultAnnexSubclause}.
* @param defaultAnnexSection Either the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}.
* @param annexText Either the value of {@link DefaultAnnexLibrary#getSourceText()} or
* {@link DefaultAnnexSubclause#getSourceText()}.
* @param filename Name of the AADL file containing the annex section.
* @param diagnosticsConsumer Used for handling error, warning, and info messages.
* @param parserFunction Either
* {@link AnnexParser#parseAnnexLibrary(String, String, String, int, int, ParseErrorReporter)}
* or
* {@link AnnexParser#parseAnnexSubclause(String, String, String, int, int, ParseErrorReporter)}.
* @param setParsedAnnexSection Either {@link DefaultAnnexLibrary#setSourceText(String)} or
* {@link DefaultAnnexSubclause#setSourceText(String)}.
* @param copyModes Function for copying modes from the {@link DefaultAnnexSubclause} into the newly created
* {@link AnnexSubclause}. When processing an annex library, {@code copyModes} is expected to be a
* no-op {@link Consumer}.
*/
private <A extends NamedElement, D extends A> void processAnnexSection(D defaultAnnexSection, String annexText, String filename, IDiagnosticConsumer diagnosticsConsumer, ParserFunction<A> parserFunction, Consumer<A> setParsedAnnexSection, Consumer<A> copyModes) {
INode node = NodeModelUtils.findActualNodeFor(defaultAnnexSection);
int line = node.getStartLine() + computeLineOffset(node);
int offset = AnnexUtil.getAnnexOffset(defaultAnnexSection);
// look for plug-in parser
String annexName = defaultAnnexSection.getName();
if (annexText != null && annexText.length() > 6 && annexName != null) {
// strip {** **} from annex text
if (annexText.startsWith("{**")) {
annexText = annexText.substring(3, annexText.length() - 3);
}
annexName = AnnexModel.filterDisabledAnnexes(defaultAnnexSection, annexName);
AnnexParser ap = PARSER_REGISTRY.getAnnexParser(annexName);
try {
QueuingParseErrorReporter parseErrReporter = new QueuingParseErrorReporter();
parseErrReporter.setContextResource(defaultAnnexSection.eResource());
if (defaultAnnexSection instanceof AnnexSubclause) {
AnnexUtil.setCurrentAnnexSubclause((AnnexSubclause) defaultAnnexSection);
}
A annexSection = parserFunction.parse(ap, annexName, annexText, filename, line, offset, parseErrReporter);
if (defaultAnnexSection instanceof AnnexSubclause) {
AnnexUtil.setCurrentAnnexSubclause(null);
}
if (ParseResultHolder.Factory.INSTANCE.adapt(defaultAnnexSection).getParseResult() == null) {
// Only consume messages for non-Xtext annexes
consumeMessages(parseErrReporter, diagnosticsConsumer, annexText, line, offset);
}
if (annexSection != null) {
annexSection.setName(annexName);
setParsedAnnexSection.accept(annexSection);
// copy in modes list
copyModes.accept(annexSection);
// now resolve reference so we get messages if we have references to undefined items
AnnexResolver resolver = RESOLVER_REGISTRY.getAnnexResolver(annexName);
AnnexLinkingService linkingService = LINKING_SERVICE_REGISTRY.getAnnexLinkingService(annexName);
if (resolver != null && parseErrReporter.getNumErrors() == 0) {
// Don't resolve any annex with parsing errors.
QueuingParseErrorReporter resolveErrReporter = new QueuingParseErrorReporter();
AnalysisErrorReporterManager resolveErrManager = new AnalysisErrorReporterManager(new AnalysisToParseErrorReporterAdapter.Factory(aadlRsrc -> resolveErrReporter));
resolver.resolveAnnex(annexName, Collections.singletonList(annexSection), resolveErrManager);
consumeMessages(resolveErrReporter, diagnosticsConsumer, annexText, line, offset);
if (resolveErrReporter.getNumErrors() != 0) {
AnnexValidator.setNoValidation(defaultAnnexSection, annexName);
}
} else if (linkingService != null) {
try {
XtextResource res = (XtextResource) defaultAnnexSection.eResource();
ILinker linker = res.getLinker();
linker.linkModel(annexSection, diagnosticsConsumer);
} catch (Exception e) {
String message = "Linking Service error in " + filename + " at line " + line;
IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e);
Activator.getDefault().getLog().log(status);
}
}
}
if (parseErrReporter.getNumErrors() > 0) {
AnnexValidator.setNoValidation(defaultAnnexSection, annexName);
}
} catch (RecognitionException e) {
String message = "Major parsing error in " + filename + " at line " + line;
IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e);
Activator.getDefault().getLog().log(status);
}
}
}
Aggregations