internal static void PopulateDependencies(string assetPath, List <string> dependencies)
        {
            var contents = File.ReadAllText(assetPath);

            if (string.IsNullOrEmpty(contents))
            {
                return;
            }

            var styleSheet            = s_Parser.Parse(contents);
            var importDirectivesCount = styleSheet.ImportDirectives.Count;

            s_StyleSheetProjectRelativeImportPaths.Clear();
            for (var i = 0; i < importDirectivesCount; ++i)
            {
                var importedPath = styleSheet.ImportDirectives[i].Href;
                var importResult = URIHelpers.ValidAssetURL(assetPath, importedPath, out _, out var projectRelativePath);
                if (importResult == URIValidationResult.OK)
                {
                    if (!s_StyleSheetProjectRelativeImportPaths.Contains(projectRelativePath))
                    {
                        s_StyleSheetProjectRelativeImportPaths.Add(projectRelativePath);
                    }
                }
            }

            foreach (var projectRelativeImportPath in s_StyleSheetProjectRelativeImportPaths)
            {
                if (s_StyleSheetsUnsortedDependencies.Contains(projectRelativeImportPath))
                {
                    s_StyleSheetsWithCircularImportDependencies.Add(projectRelativeImportPath);
                    throw new InvalidDataException("Circular @import dependencies");
                }

                s_StyleSheetsUnsortedDependencies.Add(projectRelativeImportPath);
                PopulateDependencies(projectRelativeImportPath, dependencies);
                dependencies.Add(projectRelativeImportPath);
            }
        }
        protected void ImportParserStyleSheet(UnityStyleSheet asset, ParserStyleSheet styleSheet)
        {
            m_Errors.assetPath = assetPath;

            if (styleSheet.Errors.Count > 0)
            {
                foreach (StylesheetParseError error in styleSheet.Errors)
                {
                    m_Errors.AddSyntaxError(error.ToString());
                }
            }
            else
            {
                try
                {
                    VisitSheet(styleSheet);
                }
                catch (Exception exc)
                {
                    Debug.LogException(exc);
                    m_Errors.AddInternalError(exc.StackTrace);
                }
            }

            bool success = !m_Errors.hasErrors;

            if (success)
            {
                m_Builder.BuildTo(asset);

                if (!s_StyleSheetsWithCircularImportDependencies.Contains(assetPath))
                {
                    var importDirectivesCount = styleSheet.ImportDirectives.Count;
                    asset.imports = new UnityStyleSheet.ImportStruct[importDirectivesCount];
                    for (int i = 0; i < importDirectivesCount; ++i)
                    {
                        var importedPath = styleSheet.ImportDirectives[i].Href;

                        string projectRelativePath, errorMessage;

                        URIValidationResult importResult = URIHelpers.ValidAssetURL(assetPath, importedPath, out errorMessage, out projectRelativePath);

                        UnityStyleSheet importedStyleSheet = null;
                        if (importResult != URIValidationResult.OK)
                        {
                            m_Errors.AddSemanticError(ConvertErrorCode(importResult), errorMessage);
                        }
                        else
                        {
                            importedStyleSheet = DeclareDependencyAndLoad(projectRelativePath) as UnityStyleSheet;
                            m_Context.DependsOnImportedAsset(projectRelativePath);
                        }

                        asset.imports[i] = new UnityStyleSheet.ImportStruct
                        {
                            styleSheet   = importedStyleSheet,
                            mediaQueries = styleSheet.ImportDirectives[i].Media.ToArray()
                        };
                    }

                    if (importDirectivesCount > 0)
                    {
                        asset.FlattenImportedStyleSheetsRecursive();
                    }
                }
                else
                {
                    asset.imports = new UnityStyleSheet.ImportStruct[0];
                    var errorMsg = $"The {assetPath} contains circular @import dependencies. All @import directives will be ignored for this StyleSheet.";
                    Debug.LogError(errorMsg);
                    m_Errors.AddInternalError(errorMsg);
                }

                OnImportSuccess(asset);
            }

            if (!success || m_Errors.hasWarning)
            {
                OnImportError(m_Errors);
            }
        }
        protected void ImportParserStyleSheet(UnityStyleSheet asset, ParserStyleSheet styleSheet)
        {
            m_Errors.assetPath = assetPath;

            if (styleSheet.Errors.Count > 0)
            {
                foreach (StylesheetParseError error in styleSheet.Errors)
                {
                    m_Errors.AddSyntaxError(string.Format(glossary.ussParsingError, error.Message), error.Line);
                }
            }
            else
            {
                try
                {
                    VisitSheet(styleSheet);
                }
                catch (System.Exception exc)
                {
                    m_Errors.AddInternalError(string.Format(glossary.internalErrorWithStackTrace, exc.Message, exc.StackTrace), m_CurrentLine);
                }
            }

            bool hasErrors = m_Errors.hasErrors;

            if (!hasErrors)
            {
                m_Builder.BuildTo(asset);

                if (!s_StyleSheetsWithCircularImportDependencies.Contains(assetPath))
                {
                    var importDirectivesCount = styleSheet.ImportDirectives.Count;
                    asset.imports = new UnityStyleSheet.ImportStruct[importDirectivesCount];
                    for (int i = 0; i < importDirectivesCount; ++i)
                    {
                        var importedPath = styleSheet.ImportDirectives[i].Href;

                        var response            = URIHelpers.ValidateAssetURL(assetPath, importedPath);
                        var importResult        = response.result;
                        var errorToken          = response.errorToken;
                        var projectRelativePath = response.resolvedProjectRelativePath;

                        if (response.hasWarningMessage)
                        {
                            m_Errors.AddValidationWarning(response.warningMessage, m_CurrentLine);
                        }

                        UnityStyleSheet importedStyleSheet = null;
                        if (importResult != URIValidationResult.OK)
                        {
                            var(code, message) = ConvertErrorCode(importResult);
                            m_Errors.AddSemanticWarning(code, string.Format(message, errorToken), m_CurrentLine);
                        }
                        else
                        {
                            importedStyleSheet = response.resolvedQueryAsset as UnityStyleSheet;
                            if (importedStyleSheet)
                            {
                                m_Context.DependsOnSourceAsset(projectRelativePath);
                            }
                            else
                            {
                                importedStyleSheet = DeclareDependencyAndLoad(projectRelativePath) as UnityStyleSheet;
                            }

                            if (!response.isLibraryAsset)
                            {
                                m_Context.DependsOnImportedAsset(projectRelativePath);
                            }
                        }

                        asset.imports[i] = new UnityStyleSheet.ImportStruct
                        {
                            styleSheet   = importedStyleSheet,
                            mediaQueries = styleSheet.ImportDirectives[i].Media.ToArray()
                        };
                    }

                    if (importDirectivesCount > 0)
                    {
                        asset.FlattenImportedStyleSheetsRecursive();
                    }
                }
                else
                {
                    asset.imports = new UnityStyleSheet.ImportStruct[0];
                    m_Errors.AddValidationWarning(glossary.circularImport, -1);
                }

                OnImportSuccess(asset);
            }

            bool hasWarnings = m_Errors.hasWarning;

            asset.importedWithErrors   = hasErrors;
            asset.importedWithWarnings = hasWarnings;

            if (hasErrors || hasWarnings)
            {
                OnImportError(m_Errors);
            }
        }
        protected void VisitUrlFunction(PrimitiveTerm term)
        {
            string path = (string)term.Value;

            string projectRelativePath, subAssetPath, errorMessage;

            URIValidationResult result = URIHelpers.ValidAssetURL(assetPath, path, out errorMessage, out projectRelativePath, out subAssetPath);

            if (result != URIValidationResult.OK)
            {
                m_Builder.AddValue(path, StyleValueType.MissingAssetReference);
                m_Errors.AddValidationWarning(errorMessage, m_Builder.currentProperty.line);
            }
            else
            {
                UnityEngine.Object asset = DeclareDependencyAndLoad(projectRelativePath, subAssetPath);

                bool   isTexture   = asset is Texture2D;
                Sprite spriteAsset = asset as Sprite;

                if (isTexture && string.IsNullOrEmpty(subAssetPath))
                {
                    // Try to load a sprite sub-asset associated with this texture.
                    // Sprites have extra data, such as slices and tight-meshes that
                    // aren't stored in plain textures.
                    spriteAsset = AssetDatabase.LoadAssetAtPath <Sprite>(projectRelativePath);
                }

                if (isTexture || spriteAsset != null || asset is Font || IsFontAssetInternal(asset) || asset is VectorImage || asset is RenderTexture)
                {
                    // Looking suffixed images files only
                    if (isTexture)
                    {
                        string hiResImageLocation = URIHelpers.InjectFileNameSuffix(projectRelativePath, "@2x");

                        if (File.Exists(hiResImageLocation))
                        {
                            UnityEngine.Object hiResImage = DeclareDependencyAndLoad(hiResImageLocation);

                            if (hiResImage is Texture2D)
                            {
                                m_Builder.AddValue(new ScalableImage()
                                {
                                    normalImage = asset as Texture2D, highResolutionImage = hiResImage as Texture2D
                                });
                            }
                            else
                            {
                                m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidHighResolutionImage, string.Format("Invalid asset type {0}, only Texture2D is supported for variants with @2x suffix", asset.GetType().Name));
                            }
                            return;
                        }
                        // If we didn't find an high res variant, tell ADB we depend on that potential file existing
                        if (spriteAsset != null)
                        {
                            DeclareDependencyAndLoad(hiResImageLocation);
                        }
                    }

                    m_Builder.AddValue(spriteAsset != null ? spriteAsset : asset);
                }
                else
                {
                    m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidURIProjectAssetType, string.Format("Invalid asset type {0}, only Font, FontAssets, Sprite, Texture2D and VectorImage are supported", asset.GetType().Name));
                }
            }
        }
        protected void VisitUrlFunction(PrimitiveTerm term)
        {
            string path = (string)term.Value;

            var response = URIHelpers.ValidateAssetURL(assetPath, path);

            if (response.hasWarningMessage)
            {
                m_Errors.AddValidationWarning(response.warningMessage, m_CurrentLine);
            }

            if (response.result != URIValidationResult.OK)
            {
                var(_, message) = ConvertErrorCode(response.result);

                m_Builder.AddValue(path, StyleValueType.MissingAssetReference);
                m_Errors.AddValidationWarning(string.Format(message, response.errorToken), m_CurrentLine);
            }
            else
            {
                var projectRelativePath = response.resolvedProjectRelativePath;
                var subAssetPath        = response.resolvedSubAssetPath;
                var asset = response.resolvedQueryAsset;

                if (asset)
                {
                    if (response.isLibraryAsset)
                    {
                        // do not add path dependencies on assets in the Library folder (e.g. built-in resources)
                        m_Builder.AddValue(asset);
                        return;
                    }

                    // explicit asset reference already loaded
                    m_Context?.DependsOnSourceAsset(projectRelativePath);
                }
                else
                {
                    asset = DeclareDependencyAndLoad(projectRelativePath, subAssetPath);
                }

                bool   isTexture   = asset is Texture2D;
                Sprite spriteAsset = asset as Sprite;

                if (isTexture && string.IsNullOrEmpty(subAssetPath))
                {
                    // Try to load a sprite sub-asset associated with this texture.
                    // Sprites have extra data, such as slices and tight-meshes that
                    // aren't stored in plain textures.
                    spriteAsset = AssetDatabase.LoadAssetAtPath <Sprite>(projectRelativePath);
                }

                if (asset != null)
                {
                    // Looking suffixed images files only
                    if (isTexture)
                    {
                        string hiResImageLocation = URIHelpers.InjectFileNameSuffix(projectRelativePath, "@2x");

                        if (File.Exists(hiResImageLocation))
                        {
                            UnityEngine.Object hiResImage = DeclareDependencyAndLoad(hiResImageLocation);

                            if (hiResImage is Texture2D)
                            {
                                m_Builder.AddValue(new ScalableImage()
                                {
                                    normalImage = asset as Texture2D, highResolutionImage = hiResImage as Texture2D
                                });
                            }
                            else
                            {
                                m_Errors.AddSemanticError(StyleSheetImportErrorCode.InvalidHighResolutionImage, string.Format(glossary.invalidHighResAssetType, asset.GetType().Name, projectRelativePath), m_CurrentLine);
                            }
                            return;
                        }
                        // If we didn't find an high res variant, tell ADB we depend on that potential file existing
                        if (spriteAsset != null)
                        {
                            DeclareDependencyAndLoad(hiResImageLocation);
                        }
                    }

                    Object assetToStore = spriteAsset != null ? spriteAsset : asset;

                    m_Builder.AddValue(assetToStore);

                    if (!disableValidation)
                    {
                        var propertyName = new StylePropertyName(m_Builder.currentProperty.name);

                        // Unknown properties (not custom) should beforehand
                        if (propertyName.id == StylePropertyId.Unknown)
                        {
                            return;
                        }

                        var allowed = StylePropertyUtil.GetAllowedAssetTypesForProperty(propertyName.id);

                        // If no types were returned, it means this property doesn't support assets.
                        // Normal syntax validation should cover this.
                        if (!allowed.Any())
                        {
                            return;
                        }

                        Type assetType = assetToStore.GetType();

                        // If none of the allowed types are compatible with the asset type, output a warning
                        if (!allowed.Any(t => t.IsAssignableFrom(assetType)))
                        {
                            string allowedTypes = string.Join(", ", allowed.Select(t => t.Name));
                            m_Errors.AddValidationWarning(
                                string.Format(glossary.invalidAssetType, assetType.Name, projectRelativePath, allowedTypes),
                                m_CurrentLine);
                        }
                    }
                }
                else
                {
                    // Asset is actually missing OR we couldn't load it for some reason; this should result in
                    // response.result != URIValidationResult.OK (above) but if assets are deleted while Unity is
                    // already open, we fall in here instead.
                    var(_, message) = ConvertErrorCode(URIValidationResult.InvalidURIProjectAssetPath);

                    // In case of error, we still want to call AddValue, with parameters to indicate the problem, in order
                    // to keep the full layout from being discarded. We also add appropriate warnings to explain to the
                    // user what is wrong.
                    m_Builder.AddValue(path, StyleValueType.MissingAssetReference);
                    m_Errors.AddValidationWarning(string.Format(message, path), m_CurrentLine);
                }
            }
        }