static void InversePlatformCompatibility(AssemblyDefinitionState state)
        {
            var platforms = Compilation.CompilationPipeline.GetAssemblyDefinitionPlatforms();

            for (int i = 0; i < platforms.Length; ++i)
            {
                state.platformCompatibility[i] = !state.platformCompatibility[i];
            }
        }
        static void SaveAssemblyDefinitionState(AssemblyDefinitionState state)
        {
            var references = state.references;
            var platforms  = CompilationPipeline.GetAssemblyDefinitionPlatforms();

            CustomScriptAssemblyData data = new CustomScriptAssemblyData();

            data.name = state.assemblyName;

            if (state.useGUIDs)
            {
                data.references = references.Select(r =>
                {
                    var guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(r.asset));

                    if (string.IsNullOrEmpty(guid))
                    {
                        return(r.serializedReference);
                    }

                    return(CompilationPipeline.GUIDToAssemblyDefinitionReferenceGUID(guid));
                }).ToArray();
            }
            else
            {
                data.references = references.Select(r => r.name).ToArray();
            }

            data.defineConstraints = state.defineConstraints
                                     .Where(x => !string.IsNullOrEmpty(x.name))
                                     .Select(r => r.name)
                                     .ToArray();

            data.versionDefines = state.versionDefines.Select(x => new UnityEditor.Scripting.ScriptCompilation.VersionDefine
            {
                name       = x.name,
                expression = x.expression,
                define     = x.define,
            }).ToArray();

            data.autoReferenced     = state.autoReferenced;
            data.overrideReferences = state.overrideReferences;

            data.precompiledReferences = state.precompiledReferences
                                         .Select(r => r.name).ToArray();


            data.allowUnsafeCode = state.allowUnsafeCode;

            List <string> dataPlatforms = new List <string>();

            for (int i = 0; i < platforms.Length; ++i)
            {
                if (state.platformCompatibility[i])
                {
                    dataPlatforms.Add(platforms[i].Name);
                }
            }

            if (dataPlatforms.Any())
            {
                if (state.compatibleWithAnyPlatform)
                {
                    data.excludePlatforms = dataPlatforms.ToArray();
                }
                else
                {
                    data.includePlatforms = dataPlatforms.ToArray();
                }
            }

            var json = CustomScriptAssemblyData.ToJson(data);

            File.WriteAllText(state.path, json);

            AssetDatabase.ImportAsset(state.path);
        }
        static void LoadAssemblyDefintionState(AssemblyDefinitionState state, string path)
        {
            var asset = AssetDatabase.LoadAssetAtPath <AssemblyDefinitionAsset>(path);

            if (asset == null)
            {
                return;
            }

            var data = CustomScriptAssemblyData.FromJsonNoFieldValidation(asset.text);

            if (data == null)
            {
                return;
            }

            try
            {
                data.ValidateFields();
            }
            catch (Exception e)
            {
                Debug.LogException(e, asset);
            }

            state.asset                 = asset;
            state.assemblyName          = data.name;
            state.references            = new List <AssemblyDefinitionReference>();
            state.precompiledReferences = new List <PrecompiledReference>();
            state.defineConstraints     = new List <DefineConstraint>();
            state.versionDefines        = new List <VersionDefine>();
            state.autoReferenced        = data.autoReferenced;
            state.allowUnsafeCode       = data.allowUnsafeCode;
            state.overrideReferences    = data.overrideReferences;

            // If the .asmdef has no references (true for newly created .asmdef), then use GUIDs.
            // Otherwise do not use GUIDs. This value might be changed below if any reference is a GUID.
            state.useGUIDs = (data.references == null || data.references.Length == 0);

            if (data.versionDefines != null)
            {
                foreach (var versionDefine in data.versionDefines)
                {
                    if (!SymbolNameRestrictions.IsValid(versionDefine.define))
                    {
                        var exception = new AssemblyDefinitionException($"Invalid version define {versionDefine.define}", path);
                        Debug.LogException(exception, asset);
                    }
                    else
                    {
                        state.versionDefines.Add(new VersionDefine
                        {
                            name       = versionDefine.name,
                            expression = versionDefine.expression,
                            define     = versionDefine.define,
                        });
                    }
                }
            }

            if (data.defineConstraints != null)
            {
                foreach (var defineConstraint in data.defineConstraints)
                {
                    var symbolName = defineConstraint.StartsWith(DefineConstraintsHelper.Not) ? defineConstraint.Substring(1) : defineConstraint;
                    if (!SymbolNameRestrictions.IsValid(symbolName))
                    {
                        var exception = new AssemblyDefinitionException($"Invalid define constraint {symbolName}", path);
                        Debug.LogException(exception, asset);
                    }
                    else
                    {
                        state.defineConstraints.Add(new DefineConstraint
                        {
                            name = defineConstraint,
                        });
                    }
                }
            }

            if (data.references != null)
            {
                foreach (var reference in data.references)
                {
                    try
                    {
                        var assemblyDefinitionFile = new AssemblyDefinitionReference
                        {
                            name = reference,
                            serializedReference = reference
                        };

                        // If any references is a GUID, use GUIDs.
                        var isGuid = CompilationPipeline.GetAssemblyDefinitionReferenceType(reference) == AssemblyDefinitionReferenceType.Guid;
                        if (isGuid)
                        {
                            state.useGUIDs = true;
                        }

                        assemblyDefinitionFile.Load(reference, isGuid);
                        state.references.Add(assemblyDefinitionFile);
                    }
                    catch (AssemblyDefinitionException e)
                    {
                        UnityEngine.Debug.LogException(e, asset);
                        state.references.Add(new AssemblyDefinitionReference());
                    }
                }
            }

            var nameToPrecompiledReference = EditorCompilationInterface.Instance.GetAllPrecompiledAssemblies()
                                             .Where(x => (x.Flags & AssemblyFlags.UserAssembly) == AssemblyFlags.UserAssembly)
                                             .ToDictionary(x => AssetPath.GetFileName(x.Path), x => x);

            foreach (var precompiledReferenceName in data.precompiledReferences ?? Enumerable.Empty <String>())
            {
                try
                {
                    var precompiledReference = new PrecompiledReference
                    {
                        name = precompiledReferenceName,
                    };

                    PrecompiledAssembly assembly;
                    if (nameToPrecompiledReference.TryGetValue(precompiledReferenceName, out assembly))
                    {
                        precompiledReference.path     = assembly.Path;
                        precompiledReference.fileName = AssetPath.GetFileName(assembly.Path);
                    }
                    state.precompiledReferences.Add(precompiledReference);
                }
                catch (AssemblyDefinitionException e)
                {
                    Debug.LogException(e, asset);
                    state.precompiledReferences.Add(new PrecompiledReference());
                }
            }

            var platforms = CompilationPipeline.GetAssemblyDefinitionPlatforms();

            state.platformCompatibility = new bool[platforms.Length];

            state.compatibleWithAnyPlatform = true;
            string[] dataPlatforms = null;

            if (data.includePlatforms != null && data.includePlatforms.Length > 0)
            {
                state.compatibleWithAnyPlatform = false;
                dataPlatforms = data.includePlatforms;
            }
            else if (data.excludePlatforms != null && data.excludePlatforms.Length > 0)
            {
                state.compatibleWithAnyPlatform = true;
                dataPlatforms = data.excludePlatforms;
            }

            if (dataPlatforms != null)
            {
                foreach (var platform in dataPlatforms)
                {
                    var platformIndex = GetPlatformIndex(platforms, platform);
                    state.platformCompatibility[platformIndex] = true;
                }
            }
        }