private bool ProcessFile()

in src/Tasks/GenerateResource.cs [2454:2713]


        private bool ProcessFile(string inFile, string outFileOrDir)
        {
            Format inFileFormat = GetFormat(inFile);
            if (inFileFormat == Format.Error)
            {
                // GetFormat would have logged an error.
                return false;
            }
            if (inFileFormat != Format.Assembly) // outFileOrDir is a directory when the input file is an assembly
            {
                Format outFileFormat = GetFormat(outFileOrDir);
                if (outFileFormat == Format.Assembly)
                {
                    _logger.LogErrorFromResources("GenerateResource.CannotWriteAssembly", outFileOrDir);
                    return false;
                }
                else if (outFileFormat == Format.Error)
                {
                    return false;
                }
            }

            if (!_extractResWFiles)
            {
                _logger.LogMessageFromResources("GenerateResource.ProcessingFile", inFile, outFileOrDir);
            }

            // Reset state
            _readers = new List<ReaderInfo>();

            try
            {
                ReadResources(inFile, _useSourcePath, outFileOrDir);
            }
            catch (ArgumentException ae)
            {
                if (ae.InnerException is XmlException)
                {
                    XmlException xe = (XmlException) ae.InnerException;
                    _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), xe.LineNumber,
                        xe.LinePosition, 0, 0, "General.InvalidResxFile", xe.Message);
                }
                else
                {
                    _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), 0, 0, 0, 0,
                        "General.InvalidResxFile", ae.Message);
                }
                return false;
            }
            catch (TextFileException tfe)
            {
                // Used to pass back error context from ReadTextResources to here.
                _logger.LogErrorWithCodeFromResources(null, tfe.FileName, tfe.LineNumber, tfe.LinePosition, 1, 1,
                    "GenerateResource.MessageTunnel", tfe.Message);
                return false;
            }
            catch (XmlException xe)
            {
                _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), xe.LineNumber,
                    xe.LinePosition, 0, 0, "General.InvalidResxFile", xe.Message);
                return false;
            }
            catch (Exception e) when (
#if FEATURE_BINARY_SERIALIZATION
                                      e is SerializationException ||
#endif
                                      e is TargetInvocationException)
            {
                // DDB #9819
                // SerializationException and TargetInvocationException can occur when trying to deserialize a type from a resource format (typically with other exceptions inside)
                // This is a bug in the type being serialized, so the best we can do is dump diagnostic information and move on to the next input resource file.
                _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), 0, 0, 0, 0,
                    "General.InvalidResxFile", e.Message);

                // Log the stack, so the problem with the type in the .resx is diagnosable by the customer
                _logger.LogErrorFromException(e, /* stack */ true, /* inner exceptions */ true,
                    FileUtilities.GetFullPathNoThrow(inFile));
                return false;
            }
            catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e))
            {
                // Regular IO error
                _logger.LogErrorWithCodeFromResources(null, FileUtilities.GetFullPathNoThrow(inFile), 0, 0, 0, 0,
                    "General.InvalidResxFile", e.Message);
                return false;
            }

            string currentOutputFile = null;
            string currentOutputDirectory = null;
            string currentOutputSourceCodeFile = null;
            bool currentOutputDirectoryAlreadyExisted = true;

            try
            {
                if (GetFormat(inFile) == Format.Assembly)
                {
#if FEATURE_BINARY_SERIALIZATION
                    // Prepare cache data
                    ResGenDependencies.PortableLibraryFile library = new ResGenDependencies.PortableLibraryFile(inFile);
#endif
                    List<string> resWFilesForThisAssembly = new List<string>();

                    foreach (ReaderInfo reader in _readers)
                    {
                        String currentOutputFileNoPath = reader.outputFileName + ".resw";
                        currentOutputFile = null;
                        currentOutputDirectoryAlreadyExisted = true;
                        string priDirectory = Path.Combine(outFileOrDir ?? String.Empty,
                            reader.assemblySimpleName);
                        currentOutputDirectory = Path.Combine(priDirectory,
                            reader.cultureName ?? String.Empty);

                        if (!Directory.Exists(currentOutputDirectory))
                        {
                            currentOutputDirectoryAlreadyExisted = false;
                            Directory.CreateDirectory(currentOutputDirectory);
                        }
                        currentOutputFile = Path.Combine(currentOutputDirectory, currentOutputFileNoPath);

                        // For very long resource names, this directory structure may be too deep.
                        // If so, assume that the name is so long it will already uniquely distinguish itself.
                        // However for shorter names we'd still prefer to use the assembly simple name
                        // in the path to avoid conflicts.
                        currentOutputFile = EnsurePathIsShortEnough(currentOutputFile, currentOutputFileNoPath,
                            outFileOrDir, reader.cultureName);

                        if (currentOutputFile == null)
                        {
                            // We couldn't generate a file name short enough to handle this.  Fail but continue.
                            continue;
                        }

                        // Always write the output file here - other logic prevents us from processing this 
                        // file for incremental builds if everything was up to date.
                        WriteResources(reader, currentOutputFile);

                        string escapedOutputFile = EscapingUtilities.Escape(currentOutputFile);
                        ITaskItem newOutputFile = new TaskItem(escapedOutputFile);
                        resWFilesForThisAssembly.Add(escapedOutputFile);
                        newOutputFile.SetMetadata("ResourceIndexName", reader.assemblySimpleName);
#if FEATURE_BINARY_SERIALIZATION
                        library.AssemblySimpleName = reader.assemblySimpleName;
#endif
                        if (reader.fromNeutralResources)
                        {
                            newOutputFile.SetMetadata("NeutralResourceLanguage", reader.cultureName);
#if FEATURE_BINARY_SERIALIZATION
                            library.NeutralResourceLanguage = reader.cultureName;
#endif
                        }
                        ExtractedResWFiles.Add(newOutputFile);
                    }

#if FEATURE_BINARY_SERIALIZATION
                    library.OutputFiles = resWFilesForThisAssembly.ToArray();
                    _portableLibraryCacheInfo.Add(library);
#endif
                }
                else
                {
                    currentOutputFile = outFileOrDir;
                    ErrorUtilities.VerifyThrow(_readers.Count == 1,
                        "We have no readers, or we have multiple readers & are ignoring subsequent ones.  Num readers: {0}",
                        _readers.Count);
                    WriteResources(_readers[0], outFileOrDir);
                }

                if (_stronglyTypedLanguage != null)
                {
                    try
                    {
                        ErrorUtilities.VerifyThrow(_readers.Count == 1,
                            "We have no readers, or we have multiple readers & are ignoring subsequent ones.  Num readers: {0}",
                            _readers.Count);
                        CreateStronglyTypedResources(_readers[0], outFileOrDir, inFile, out currentOutputSourceCodeFile);
                    }
                    catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e))
                    {
                        // IO Error
                        _logger.LogErrorWithCodeFromResources("GenerateResource.CannotWriteSTRFile",
                            _stronglyTypedFilename, e.Message);

                        if (File.Exists(outFileOrDir)
                            && GetFormat(inFile) != Format.Assembly
                            // outFileOrDir is a directory when the input file is an assembly
                            && GetFormat(outFileOrDir) != Format.Assembly)
                            // Never delete an assembly since we don't ever actually write to assemblies.
                        {
                            RemoveCorruptedFile(outFileOrDir);
                        }
                        if (currentOutputSourceCodeFile != null)
                        {
                            RemoveCorruptedFile(currentOutputSourceCodeFile);
                        }
                        return false;
                    }
                }
            }
            catch (IOException io)
            {
                if (currentOutputFile != null)
                {
                    _logger.LogErrorWithCodeFromResources("GenerateResource.CannotWriteOutput",
                        FileUtilities.GetFullPathNoThrow(currentOutputFile), io.Message);
                    if (File.Exists(currentOutputFile))
                    {
                        if (GetFormat(currentOutputFile) != Format.Assembly)
                            // Never delete an assembly since we don't ever actually write to assemblies.
                        {
                            RemoveCorruptedFile(currentOutputFile);
                        }
                    }
                }

                if (currentOutputDirectory != null &&
                    currentOutputDirectoryAlreadyExisted == false)
                {
                    // Do not annoy the user by removing an empty directory we did not create.
                    try
                    {
                        Directory.Delete(currentOutputDirectory); // Remove output directory if empty
                    }
                    catch (Exception e)
                    {
                        // Fail silently (we are not even checking if the call to File.Delete succeeded)
                        if (ExceptionHandling.IsCriticalException(e))
                        {
                            throw;
                        }
                    }
                }
                return false;
            }
            catch (Exception e) when (
#if FEATURE_BINARY_SERIALIZATION
                                      e is SerializationException ||
#endif
                                      e is TargetInvocationException)
            {
                // DDB #9819
                // SerializationException and TargetInvocationException can occur when trying to serialize a type into a resource format (typically with other exceptions inside)
                // This is a bug in the type being serialized, so the best we can do is dump diagnostic information and move on to the next input resource file.
                _logger.LogErrorWithCodeFromResources("GenerateResource.CannotWriteOutput",
                    FileUtilities.GetFullPathNoThrow(inFile), e.Message); // Input file is more useful to log

                // Log the stack, so the problem with the type in the .resx is diagnosable by the customer
                _logger.LogErrorFromException(e, /* stack */ true, /* inner exceptions */ true,
                    FileUtilities.GetFullPathNoThrow(inFile));
                return false;
            }
            catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e))
            {
                // Regular IO error
                _logger.LogErrorWithCodeFromResources("GenerateResource.CannotWriteOutput",
                    FileUtilities.GetFullPathNoThrow(currentOutputFile), e.Message);
                return false;
            }

            return true;
        }