@SuppressWarnings("unchecked")
	@Override
	public boolean read(Map<String, Object> result, SarifProgramOptions options,
			TaskMonitor monitor) throws AddressFormatException, CancelledException {

		DataTypeManager dataManager = listing.getDataTypeManager();
		BuiltInDataTypeManager builtInMgr = BuiltInDataTypeManager.getDataTypeManager();

		try {
			dtParser = new DtParser(dataManager);

			try {
				String msgKey = (String) result.get("Message");
				boolean isThunk = (boolean) result.get("isThunk");
				boolean process = (firstPass && !isThunk) || (!firstPass && isThunk);
				if (!msgKey.equals("Function") || !process) {
					return true;
				}

				Address entryPoint = getEntryPoint(result);
				// Grab the original symbols
				Symbol[] symbols = program.getSymbolTable().getSymbols(entryPoint);

				Function func = createFunction(result, isThunk, entryPoint);

				// Restore the original labels
				for (Symbol symbol : symbols) {
					SourceType srcType = symbol.getSource();
					if (!srcType.equals(SourceType.DEFAULT)) {
						program.getSymbolTable()
								.createLabel(entryPoint, symbol.getName(true), srcType);
					}
				}

				String source = (String) result.get("sourceType");
				SourceType sourceType =
					source.equals("DEFAULT") ? SourceType.IMPORTED : getSourceType(source);
				String typeInfoComment = setProperties(result, func, entryPoint);

				// Process stack
				List<Variable> stackParams = new ArrayList<>();
				List<Map<String, Object>> regVars =
					(List<Map<String, Object>>) result.get("regVars");
				for (Map<String, Object> var : regVars) {
					readRegisterVars(var, func, stackParams);
				}

				Map<String, Object> stack = (Map<String, Object>) result.get("stack");
				readStackFrame(stack, func, stackParams, sourceType);

				List<Map<String, Object>> parms = (List<Map<String, Object>>) result.get("params");
				List<Variable> formalParams = new ArrayList<>();
				for (Map<String, Object> p : parms) {
					readParameter(p, func, formalParams);
				}

				// Process formal parameters and return
				Map<String, Object> ret = (Map<String, Object>) result.get("ret");
				ReturnParameterImpl retImpl = null;
				if (ret != null) {
					retImpl = readReturnType(ret, func);
				}
				List<Variable> plist = stackParams;
				if (typeInfoComment != null) {
					plist = formalParams;
				}

				updateFunction(func, retImpl, plist, sourceType);

				postProcess(result, func, stack);

			}
			catch (Exception e) {
				log.appendException(e);
			}
		}
		finally {
			builtInMgr.close();
		}
		return true;
	}
Parses a list of {@link Function function} definitions from SARIF and creates
then, adding them to the current {@link Program program}.
<p>
Information from a TYPEINFO_COMMENT is used in preference to information from
RETURN_TYPE and STACK_FRAME/STACK_VARs that are tagged as parameters.
<p>
DTD for the FUNCTION element:

<pre>
<code>
&lt;!ELEMENT FUNCTION (RETURN_TYPE?, ADDRESS_RANGE*, REGULAR_CMT?, REPEATABLE_CMT?, TYPEINFO_CMT?, STACK_FRAME?, REGISTER_VAR*)&gt;
</code>
</pre>

@param result             the parser
@param options
@param monitor            the task monitor
@throws AddressFormatException if any address is not parsable
@throws CancelledException     if the operation is cancelled through the
                               monitor
Ghidra/Features/Sarif/src/main/java/sarif/managers/FunctionsSarifMgr.java