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);
        }
示例#2
0
        /// <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
                    jToken = resourceExplorer.ResolveRefAsync(jToken, sourceContext).GetAwaiter().GetResult();
                }

                var kind = (string)jToken["$kind"];

                if (kind == null)
                {
                    // see if there is jObject resolver
                    var result = ResolveUnknownObject(jToken);
                    if (result != null)
                    {
                        return(result);
                    }

                    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 = DebugSupport.SourceMap.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;
                        }
                    }

                    // 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);
                }
            }
        }