private void processSymbol(XmlElement element, XmlPullParser parser, int passNumber) {
		try {
			String type = element.getAttribute("TYPE");
			boolean isLocal = (type != null) && type.equalsIgnoreCase("local");

			String name = element.getAttribute("NAME");
			boolean isDefaultFunctionName =
				name != null && (name.startsWith("FUN_") || name.startsWith("thunk_"));

			// Handle locals during pass-2 and all others during pass-1
			if (isLocal || isDefaultFunctionName) {
				if (passNumber != 2) {
					secondPassRequired = true;
					return;
				}
			}
			else if (passNumber == 2) {
				return;
			}

			String addrStr = element.getAttribute("ADDRESS");
			String namespace = element.getAttribute("NAMESPACE");
			if (namespace != null && namespace.endsWith("::")) {
				namespace = namespace.substring(0, namespace.length() - 2);
			}
			String primary = element.getAttribute("PRIMARY");
			String sourceTypeString = element.getAttribute("SOURCE_TYPE");

			boolean isPrimary = (primary == null) || primary.equalsIgnoreCase("y");

			SourceType sourceType = SourceType.USER_DEFINED;
			try {
				if (sourceTypeString != null) {
					sourceType = SourceType.valueOf(sourceTypeString);
				}
			}
			catch (IllegalArgumentException iae) {
				log.appendMsg("Unknown SourceType: " + sourceTypeString);
			}

			Address addr = XmlProgramUtilities.parseAddress(factory, addrStr);
			if (addr == null) {
				throw new XmlAttributeException("Incompatible Symbol Address: " + addrStr);
			}
			if (name == null) {
				throw new XmlAttributeException(
					"Missing required symbol name for address: " + addrStr);
			}

			Namespace localNamespace = symbolTable.getNamespace(addr);
			Namespace scope = program.getGlobalNamespace(); // default to global scope
			if (isLocal) {
				scope = localNamespace;
			}
			else if (localNamespace != null &&
				localNamespace.getName().equalsIgnoreCase(namespace)) {
				scope = localNamespace;
			}
			else if (namespace != null && namespace.length() != 0) {
				scope = NamespaceUtils.createNamespaceHierarchy(namespace,
					program.getGlobalNamespace(), program, sourceType);
			}

			Symbol s = symbolTable.getPrimarySymbol(addr);
			if (name.startsWith("thunk_")) {
				if (s == null || s.getSymbolType() != SymbolType.FUNCTION) {
					log.appendMsg("Thunk symbol ignored at non-function location: " + addr);
					return;
				}
				Function f = (Function) s.getObject();
				if (!f.isThunk()) {
					String thunkedName = name.substring(6);
					Symbol symbol = SymbolUtilities.getExpectedLabelOrFunctionSymbol(program,
						thunkedName, err -> log.error(null, err));
					if (symbol == null || symbol.getSymbolType() != SymbolType.FUNCTION) {
						log.appendMsg(
							"Failed to establish thunk function for function at: " + addr);
						return;
					}
					f.setThunkedFunction((Function) symbol.getObject());
				}
			}
			else if (s != null &&
				!(s.getName().equals(name) && !scope.equals(s.getParentNamespace()))) {
				s = symbolTable.getSymbol(name, addr, scope);
			}

			if (s == null) {
				s = SymbolUtilities.createPreferredLabelOrFunctionSymbol(program, addr, scope, name,
					sourceType);
			}

			if (isPrimary && overwritePrimary) {
				s.setPrimary();
			}
			if (sourceType != SourceType.DEFAULT) {
				s.setSource(sourceType);
			}
		}
		catch (Exception e) {
			log.appendException(e);
		}
	}
Returns the name of symbol qualified with
any namespace information.
For example, "User32.dll::SomeClass::printf".
Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/SymbolTableXmlMgr.java