private IList <DocumentContext> ParseDocument(Uri uri, IList <DocumentContext> contexts = null, ISet <Uri> parsedUris = null, Stack <Uri> parentDocuments = null, TypeRegistry typeRegistry = null) { // This is only for the first call. contexts = contexts ?? new List <DocumentContext>(); parsedUris = parsedUris ?? new HashSet <Uri>(); parentDocuments = parentDocuments ?? new Stack <Uri>(); typeRegistry = typeRegistry ?? new TypeRegistry(); if (uri == null || !uri.IsAbsoluteUri) { throw new ArgumentException("Only absolute URIs can be parsed!"); } if (parentDocuments.Contains(uri)) { throw new ArgumentException(string.Format("Input {0} recursively includes itself ({1})", uri, string.Join(" -> ", parentDocuments) + " -> " + uri)); } LOG.Debug(string.Format("Parsing {0}...", uri)); var idlNamespace = ExtractNamespace(uri); if (string.IsNullOrWhiteSpace(idlNamespace)) { throw new ArgumentException(string.Format("URI {0} can not be translated to a namespace", uri)); } var context = CreateDocumentContext(uri, idlNamespace, _generatorConfig, typeRegistry); var document = context.Document; var header = document.Header; // Make a note that this document is a parent of all the documents included, directly or recursively parentDocuments.Push(uri); try { if (header != null) { foreach (var include in header.Includes) { Uri includeUri; Uri.TryCreate(_generatorConfig.InputBase, include, out includeUri); ParseDocument(includeUri, // If the includes should also generate code, pass the list of // contexts down to the include parser, otherwise pass a null in _generatorConfig.GenerateIncludedCode ? contexts : null, parsedUris, parentDocuments, typeRegistry); } } } finally { // Done parsing this document's includes, remove it from the parent chain parentDocuments.Pop(); } // Make a note that we've already passed this document if (!parsedUris.Contains(uri)) { CreateTypeVisitor(context.CodeNamespace, context).Visit(document); parsedUris.Add(uri); contexts.Add(context); } return(contexts); }
protected abstract DocumentContext CreateDocumentContext(Uri uri, string idlNamespace, GeneratorConfig config, TypeRegistry typeRegistry);
private void ParseDocument(Uri uri, IDictionary <string, DocumentContext> contexts, TypeRegistry typeRegistry) { if (uri == null || !uri.IsAbsoluteUri) { throw new ArgumentException("Only absolute URIs can be parsed!"); } if (_parentDocuments.Contains(uri)) { throw new ArgumentException(string.Format("Input {0} recursively includes itself ({1})", uri, string.Join(" -> ", _parentDocuments) + " -> " + uri)); } if (_parsedDocuments.Contains(uri)) { LOG.Debug(string.Format("Skipping already parsed file {0}...", uri)); return; } LOG.Debug(string.Format("Parsing {0}...", uri)); var idlNamespace = ExtractNamespace(uri); if (string.IsNullOrWhiteSpace(idlNamespace)) { throw new ArgumentException(string.Format("URI {0} can not be translated to a namespace", uri)); } var context = CreateDocumentContext(uri, idlNamespace, _generatorConfig, typeRegistry); var document = context.Document; var header = document.Header; var codeNamespace = context.CodeNamespace; // Make a note that this document is a parent of all the documents included, directly or recursively _parentDocuments.Push(uri); try { if (header != null) { foreach (var include in header.Includes) { Uri includeUri; Uri.TryCreate(_generatorConfig.InputBase, include, out includeUri); ParseDocument(includeUri, // If the includes should also generate code, pass the list of // contexts down to the include parser, otherwise pass a null in _generatorConfig.GenerateIncludedCode ? contexts : null, typeRegistry); } } } finally { // Done parsing this document's includes, remove it from the parent chain _parentDocuments.Pop(); } // Make a note that we've already passed this document _parsedDocuments.Add(uri); new TypeVisitor(codeNamespace, context).Visit(document); if (contexts != null) { if (contexts.ContainsKey(context.Namespace)) { LOG.Info(string.Format("Namespace {0} included multiple times!", context.Namespace)); } contexts[context.Namespace] = context; } }