JsonReferenceVisitorBase
Visitor to transform an object with JsonSchema4 objects.
using Microsoft.Runtime.CompilerServices;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NJsonSchema.Infrastructure;
using NJsonSchema.References;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace NJsonSchema.Visitors
{
public abstract class JsonReferenceVisitorBase
{
private readonly IContractResolver _contractResolver;
private readonly string[] _jsonSchemaProperties = (from p in ReflectionExtensions.GetRuntimeProperties(typeof(JsonSchema4))
select p.Name).ToArray();
protected JsonReferenceVisitorBase()
: this(new DefaultContractResolver())
{
}
protected JsonReferenceVisitorBase(IContractResolver contractResolver)
{
_contractResolver = contractResolver;
}
public virtual async Task VisitAsync(object obj)
{
ConfiguredTaskAwaitable val = AwaitExtensions.ConfigureAwait(VisitAsync(obj, "#", null, new HashSet<object>(), delegate {
throw new NotSupportedException("Cannot replace the root.");
}), false);
ConfiguredTaskAwaiter val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
}
val2.GetResult();
}
protected abstract Task<IJsonReference> VisitJsonReferenceAsync(IJsonReference reference, string path, string typeNameHint);
protected virtual async Task VisitAsync(object obj, string path, string typeNameHint, ISet<object> checkedObjects, Action<object> replacer)
{
if (obj != null && !checkedObjects.Contains(obj)) {
checkedObjects.Add(obj);
IJsonReference jsonReference;
IJsonReference reference = jsonReference = (obj as IJsonReference);
if (jsonReference != null) {
ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<IJsonReference>(VisitJsonReferenceAsync(reference, path, typeNameHint), false).GetAwaiter();
if (!val.get_IsCompleted()) {
await val;
ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter);
val = val2;
}
IJsonReference result = (IJsonReference)val.GetResult();
if (result != reference) {
replacer(result);
return;
}
}
JsonSchema4 schema;
ConfiguredTaskAwaitable val3;
ConfiguredTaskAwaiter val4;
ConfiguredTaskAwaiter val5 = default(ConfiguredTaskAwaiter);
if ((schema = (obj as JsonSchema4)) != null) {
if (schema.Reference != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.Reference, path, null, checkedObjects, delegate(object o) {
schema.Reference = (JsonSchema4)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
if (schema.AdditionalItemsSchema != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.AdditionalItemsSchema, path + "/additionalItems", null, checkedObjects, delegate(object o) {
schema.AdditionalItemsSchema = (JsonSchema4)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
if (schema.AdditionalPropertiesSchema != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.AdditionalPropertiesSchema, path + "/additionalProperties", null, checkedObjects, delegate(object o) {
schema.AdditionalPropertiesSchema = (JsonSchema4)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
if (schema.Item != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.Item, path + "/items", null, checkedObjects, delegate(object o) {
schema.Item = (JsonSchema4)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
for (int l = 0; l < schema.Items.Count; l++) {
int index = l;
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.Items.ElementAt(l), path + "/items[" + l + "]", null, checkedObjects, delegate(object o) {
ReplaceOrDelete(schema.Items, index, (JsonSchema4)o);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
for (int l = 0; l < schema.AllOf.Count; l++) {
int index2 = l;
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.AllOf.ElementAt(l), path + "/allOf[" + l + "]", null, checkedObjects, delegate(object o) {
ReplaceOrDelete(schema.AllOf, index2, (JsonSchema4)o);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
for (int l = 0; l < schema.AnyOf.Count; l++) {
int index3 = l;
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.AnyOf.ElementAt(l), path + "/anyOf[" + l + "]", null, checkedObjects, delegate(object o) {
ReplaceOrDelete(schema.AnyOf, index3, (JsonSchema4)o);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
for (int l = 0; l < schema.OneOf.Count; l++) {
int index4 = l;
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.OneOf.ElementAt(l), path + "/oneOf[" + l + "]", null, checkedObjects, delegate(object o) {
ReplaceOrDelete(schema.OneOf, index4, (JsonSchema4)o);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
if (schema.Not != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(schema.Not, path + "/not", null, checkedObjects, delegate(object o) {
schema.Not = (JsonSchema4)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
KeyValuePair<string, JsonProperty>[] array = schema.Properties.ToArray();
for (int l = 0; l < array.Length; l++) {
KeyValuePair<string, JsonProperty> p = array[l];
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(p.Value, path + "/properties/" + p.Key, p.Key, checkedObjects, delegate(object o) {
schema.Properties[p.Key] = (JsonProperty)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
KeyValuePair<string, JsonSchema4>[] array2 = schema.PatternProperties.ToArray();
for (int l = 0; l < array2.Length; l++) {
KeyValuePair<string, JsonSchema4> p2 = array2[l];
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(p2.Value, path + "/patternProperties/" + p2.Key, null, checkedObjects, delegate(object o) {
schema.PatternProperties[p2.Key] = (JsonProperty)o;
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
array2 = schema.Definitions.ToArray();
for (int l = 0; l < array2.Length; l++) {
KeyValuePair<string, JsonSchema4> p3 = array2[l];
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(p3.Value, path + "/definitions/" + p3.Key, p3.Key, checkedObjects, delegate(object o) {
if (o != null)
schema.Definitions[p3.Key] = (JsonSchema4)o;
else
schema.Definitions.Remove(p3.Key);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
}
if (!(obj is string) && !(obj is JToken)) {
IDictionary dictionary;
IList list;
if ((dictionary = (obj as IDictionary)) != null) {
val3 = AwaitExtensions.ConfigureAwait(VisitPropertiesAsync(obj, path, checkedObjects), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
object[] array3 = dictionary.Keys.OfType<object>().ToArray();
foreach (object key in array3) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(dictionary[key], path + "/" + key, key.ToString(), checkedObjects, delegate(object o) {
if (o != null)
dictionary[key] = (JsonSchema4)o;
else
dictionary.Remove(key);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
} else if ((list = (obj as IList)) != null) {
object[] array3 = list.OfType<object>().ToArray();
for (int l = 0; l < array3.Length; l++) {
int index5 = l;
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(array3[l], path + "[" + l + "]", null, checkedObjects, delegate(object o) {
ReplaceOrDelete(list, index5, o);
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
} else {
IEnumerable obj2 = obj as IEnumerable;
if (obj2 != null) {
object[] array3 = obj2.OfType<object>().ToArray();
for (int l = 0; l < array3.Length; l++) {
val3 = AwaitExtensions.ConfigureAwait(VisitAsync(array3[l], path + "[" + l + "]", null, checkedObjects, delegate {
throw new NotSupportedException("Cannot replace enumerable item.");
}), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
val5 = default(ConfiguredTaskAwaiter);
}
val4.GetResult();
}
} else {
val3 = AwaitExtensions.ConfigureAwait(VisitPropertiesAsync(obj, path, checkedObjects), false);
val4 = val3.GetAwaiter();
if (!val4.get_IsCompleted()) {
await val4;
val4 = val5;
}
val4.GetResult();
}
}
}
}
}
private async Task VisitPropertiesAsync(object obj, string path, ISet<object> checkedObjects)
{
JsonObjectContract jsonObjectContract;
ConfiguredTaskAwaitable val;
ConfiguredTaskAwaiter val2;
if ((jsonObjectContract = (_contractResolver.ResolveContract(obj.GetType()) as JsonObjectContract)) != null) {
foreach (Newtonsoft.Json.Serialization.JsonProperty item in jsonObjectContract.Properties.Where(delegate(Newtonsoft.Json.Serialization.JsonProperty p) {
if (!p.Ignored)
return p.ShouldSerialize?.Invoke(obj) ?? true;
return false;
})) {
object value = item.ValueProvider.GetValue(obj);
if (value != null) {
val = AwaitExtensions.ConfigureAwait(VisitAsync(value, path + "/" + item.PropertyName, item.PropertyName, checkedObjects, delegate(object o) {
item.ValueProvider.SetValue(obj, o);
}), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
val3 = default(ConfiguredTaskAwaiter);
}
val2.GetResult();
}
}
} else {
foreach (ReflectionCache.PropertyOrField item2 in ReflectionCache.GetPropertiesAndFields(obj.GetType()).Where(delegate(ReflectionCache.PropertyOrField p) {
if (p.MemberInfo is PropertyInfo && (!(obj is JsonSchema4) || !_jsonSchemaProperties.Contains(p.MemberInfo.Name)) && (!(obj is IDictionary) || p.MemberInfo.DeclaringType == obj.GetType()) && p.CanRead && !p.IsIndexer)
return p.CustomAttributes.JsonIgnoreAttribute == null;
return false;
})) {
object value2 = item2.GetValue(obj);
if (value2 != null) {
val = AwaitExtensions.ConfigureAwait(VisitAsync(value2, path + "/" + item2.GetName(), item2.GetName(), checkedObjects, delegate(object o) {
item2.SetValue(obj, o);
}), false);
val2 = val.GetAwaiter();
if (!val2.get_IsCompleted()) {
await val2;
ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter);
val2 = val3;
val3 = default(ConfiguredTaskAwaiter);
}
val2.GetResult();
}
}
}
}
private void ReplaceOrDelete<T>(ICollection<T> collection, int index, T obj)
{
((Collection<T>)collection).RemoveAt(index);
if (obj != null)
((Collection<T>)collection).Insert(index, obj);
}
private void ReplaceOrDelete(IList collection, int index, object obj)
{
collection.RemoveAt(index);
if (obj != null)
collection.Insert(index, obj);
}
}
}