public void doSetNameAndNamespace(String newName, Namespace newNamespace, SourceType source,
			boolean checkForDuplicates)
			throws DuplicateNameException, InvalidInputException, CircularDependencyException {

		lock.acquire();
		try {
			checkDeleted();
			checkEditOK();

			SymbolType type = getSymbolType();

			symbolMgr.checkValidNamespaceArgument(newNamespace);

			source = validateNameSource(newName, source);

			symbolMgr.validateSource(newName, getAddress(), type, source);

			Namespace oldNamespace = getParentNamespace();
			boolean namespaceChange = !oldNamespace.equals(newNamespace);
			if (namespaceChange) {
				if (!isValidParent(newNamespace)) {
					throw new InvalidInputException("Namespace \"" + newNamespace.getName(true) +
						"\" is not valid for symbol " + getName());
				}
				if (isDescendant(newNamespace)) {
					throw new CircularDependencyException("Namespace \"" +
						newNamespace.getName(true) + "\" is a descendant of symbol " + getName());
				}
			}

			boolean nameChange = true;
			String oldName = getName();
			SourceType oldSource = getSource();
			if (source == SourceType.DEFAULT) {
				if (getSource() == SourceType.DEFAULT && !namespaceChange) {
					return;
				}
				newName = "";
			}
			else {
				SymbolUtilities.validateName(newName);
				nameChange = !oldName.equals(newName);
				if (!namespaceChange && !nameChange) {
					return;
				}

				if (checkForDuplicates) {
					symbolMgr.checkDuplicateSymbolName(address, newName, newNamespace, type);
				}
			}

			if (record != null) {

				List<SymbolDB> dynamicallyRenamedSymbols = getSymbolsDynamicallyRenamedByMyRename();
				List<String> oldDynamicallyRenamedSymbolNames = null;
				if (dynamicallyRenamedSymbols != null) {
					oldDynamicallyRenamedSymbolNames =
						new ArrayList<>(dynamicallyRenamedSymbols.size());
					for (Symbol s : dynamicallyRenamedSymbols) {
						oldDynamicallyRenamedSymbolNames.add(s.getName());
					}
				}

				record.setLongValue(SymbolDatabaseAdapter.SYMBOL_PARENT_ID_COL,
					newNamespace.getID());
				record.setString(SymbolDatabaseAdapter.SYMBOL_NAME_COL, newName);
				updateSymbolSource(record, source);
				updateRecord();
				cachedName = null;  // we can't clear it until now, since any call to getName()
									// will cause the cached name to reset to the old name
				if (namespaceChange) {
					symbolMgr.symbolNamespaceChanged(this, oldNamespace);
				}
				if (nameChange) {
					if (isExternal() && (type == SymbolType.FUNCTION || type == SymbolType.LABEL)) {
						ExternalManagerDB externalManager = symbolMgr.getExternalManager();
						ExternalLocationDB externalLocation =
							(ExternalLocationDB) externalManager.getExternalLocation(this);
						externalLocation.saveOriginalNameIfNeeded(oldNamespace, oldName, oldSource);
					}
					symbolMgr.symbolRenamed(this, oldName);
					if (dynamicallyRenamedSymbols != null) {
						ProgramDB program = symbolMgr.getProgram();
						for (int i = 0; i < dynamicallyRenamedSymbols.size(); i++) {
							Symbol s = dynamicallyRenamedSymbols.get(i);
							program.symbolChanged(s, ProgramEvent.SYMBOL_RENAMED, s.getAddress(), s,
								oldDynamicallyRenamedSymbolNames.get(i), s.getName());
						}
					}
				}

				if (type == SymbolType.NAMESPACE || type == SymbolType.CLASS) {
					// function class structure path change may impact auto-params
					symbolMgr.getProgram().getFunctionManager().invalidateCache(true);
				}
			}
			else {
				symbolMgr.convertDynamicSymbol(this, newName, newNamespace.getID(), source);
			}
		}
		finally {
			lock.release();
		}
	}
Allow symbol implementations to validate the source when setting the name of
this symbol

@param newName the new name 
@param source the source type
@return the validated source type
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/symbol/SymbolDB.java