SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext)
        {
            var             scopesRidList   = pdbMetadata.GetLocalScopeRidList(methodRid);
            SymbolScopeImpl rootScopeOrNull = null;

            if (scopesRidList.Count != 0)
            {
                var custInfos = ListCache <PdbCustomDebugInfo> .AllocList();

                var stack = ListCache <SymbolScopeImpl> .AllocList();

                var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetadata.BlobStream);
                for (int i = 0; i < scopesRidList.Count; i++)
                {
                    var  rid   = scopesRidList[i];
                    int  token = new MDToken(Table.LocalScope, rid).ToInt32();
                    bool b     = pdbMetadata.TablesStream.TryReadLocalScopeRow(rid, out var row);
                    Debug.Assert(b);
                    uint startOffset = row.StartOffset;
                    uint endOffset   = startOffset + row.Length;

                    SymbolScopeImpl parent = null;
                    while (stack.Count > 0)
                    {
                        var nextParent = stack[stack.Count - 1];
                        if (startOffset >= nextParent.StartOffset && endOffset <= nextParent.EndOffset)
                        {
                            parent = nextParent;
                            break;
                        }
                        stack.RemoveAt(stack.Count - 1);
                    }

                    Debug.Assert(parent != null || rootScopeOrNull == null);
                    custInfos.Clear();
                    GetCustomDebugInfos(token, gpContext, custInfos);
                    var customDebugInfos = custInfos.Count == 0 ? Array2.Empty <PdbCustomDebugInfo>() : custInfos.ToArray();
                    var scope            = new SymbolScopeImpl(this, parent, (int)startOffset, (int)endOffset, customDebugInfos);
                    if (rootScopeOrNull == null)
                    {
                        rootScopeOrNull = scope;
                    }
                    stack.Add(scope);
                    if (parent != null)
                    {
                        parent.childrenList.Add(scope);
                    }

                    scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext);
                    GetEndOfLists(rid, out uint variableListEnd, out uint constantListEnd);
                    ReadVariables(scope, gpContext, row.VariableList, variableListEnd);
                    ReadConstants(scope, row.ConstantList, constantListEnd);
                }

                ListCache <SymbolScopeImpl> .Free(ref stack);

                ListCache <PdbCustomDebugInfo> .Free(ref custInfos);
            }
            return(rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, Array2.Empty <PdbCustomDebugInfo>()));
        }
        PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope, GenericParamContext gpContext)
        {
            if (importScope == 0)
            {
                return(null);
            }
            const int      MAX       = 1000;
            PdbImportScope result    = null;
            PdbImportScope prevScope = null;

            for (int i = 0; importScope != 0; i++)
            {
                Debug.Assert(i < MAX);
                if (i >= MAX)
                {
                    return(null);
                }
                int token = new MDToken(Table.ImportScope, importScope).ToInt32();
                if (!pdbMetadata.TablesStream.TryReadImportScopeRow(importScope, out var row))
                {
                    return(null);
                }
                var scope = new PdbImportScope();
                GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos);
                if (result == null)
                {
                    result = scope;
                }
                if (prevScope != null)
                {
                    prevScope.Parent = scope;
                }
                importScopeBlobReader.Read(row.Imports, scope.Imports);
                prevScope   = scope;
                importScope = row.Parent;
            }

            return(result);
        }