public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonObject = SourcePoint.ReadObjectWithSourcePoints(reader, JToken.Load, out var start, out var after); if (resourceExplorer.IsRef(jsonObject)) { // We can't do this asynchronously as the Json.NET interface is synchronous jsonObject = resourceExplorer.ResolveRefAsync(jsonObject, context).GetAwaiter().GetResult(); } return(jsonObject as JObject); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonObject = SourcePoint.ReadObjectWithSourcePoints(reader, JToken.Load, out SourcePoint startPoint, out SourcePoint endPoint); if (resourceExplorer.IsRef(jsonObject)) { // We can't do this asynchronously as the Json.NET interface is synchronous jsonObject = this.resourceExplorer.ResolveRefAsync(jsonObject).GetAwaiter().GetResult(); } var kind = (string)jsonObject["$kind"]; if (kind == null) { throw new ArgumentNullException($"$kind was not found: {JsonConvert.SerializeObject(jsonObject)}"); } // if IdRefResolver made a path available for the JToken, then add it to the path stack // this maintains the stack of paths used as the source of json data var found = DebugSupport.SourceMap.TryGetValue(jsonObject, out var range); if (found) { paths.Push(range.Path); } T result = this.resourceExplorer.BuildType <T>(kind, jsonObject, serializer); // DeclarativeTypeLoader.LoadAsync only adds FileResource to the paths stack if (paths.Count > 0) { // combine the "path for the most recent JToken from IdRefResolver" or the "top root path" // with the line information for this particular json fragment and add it to the sourceMap range = new SourceRange() { Path = paths.Peek(), StartPoint = startPoint, EndPoint = endPoint }; DebugSupport.SourceMap.Add(result, range); } if (found) { paths.Pop(); } return(result); }
/// <summary> /// Reads the JSON representation of the object. /// </summary> /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing value of object being read.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var(jToken, range) = SourceScope.ReadTokenRange(reader, sourceContext); using (new SourceScope(sourceContext, range)) { string refDialogName = null; if (resourceExplorer.IsRef(jToken)) { refDialogName = jToken.Value <string>(); // We can't do this asynchronously as the Json.NET interface is synchronous var reference = resourceExplorer.ResolveRefInternalAsync(jToken, sourceContext).GetAwaiter().GetResult(); jToken = reference.token; if (!rangeReferences.ContainsKey(jToken)) { rangeReferences.Add(jToken, reference.range); } } var kind = (string)jToken["$kind"]; if (kind == null) { // see if there is jObject resolver var unKnownResult = ResolveUnknownObject(jToken); if (unKnownResult != null) { return(unKnownResult); } throw new ArgumentNullException($"$kind was not found: {JsonConvert.SerializeObject(jToken)}"); } // if reference resolution made a source context available for the JToken, then add it to the context stack var found = rangeReferences.TryGetValue(jToken, out var rangeResolved); using (var newScope = found ? new SourceScope(sourceContext, rangeResolved) : null) { var passTwo = false; foreach (var observer in this.observers) { if (observer is CycleDetectionObserver cycDetectObserver && cycDetectObserver.CycleDetectionPass == CycleDetectionPasses.PassTwo) { passTwo = true; } if (observer.OnBeforeLoadToken(sourceContext, rangeResolved ?? range, jToken, out T interceptResult)) { return(interceptResult); } } var tokenToBuild = TryAssignId(jToken, sourceContext); T result; if (passTwo && refDialogName != null && cachedRefDialogs.ContainsKey(refDialogName)) { result = cachedRefDialogs[refDialogName]; } else { result = this.resourceExplorer.BuildType <T>(kind, tokenToBuild, serializer); if (passTwo && refDialogName != null) { cachedRefDialogs[refDialogName] = result; this.resourceExplorer.UpdateResourceTokenCache(refDialogName, tokenToBuild, range); } } // Associate the most specific source context information with this item if (sourceContext.CallStack.Count > 0) { range = sourceContext.CallStack.Peek().DeepClone(); if (!DebugSupport.SourceMap.TryGetValue(result, out var _)) { DebugSupport.SourceMap.Add(result, range); } } foreach (var observer in this.observers) { if (observer.OnAfterLoadToken(sourceContext, range, jToken, result, out T interceptedResult)) { return(interceptedResult); } } return(result); } } }