Skip to content

Commit

Permalink
Prototype moving JsonData to be backed by JsonDocument (Azure#33063)
Browse files Browse the repository at this point in the history
* Add WriteTo(), ==operators, and PR FB

* export API

* Add DocumentSentiment large JSON sample and add parse and read benchmarks

* initial attempt to move to JsonElement

* some fixes

* updates

* nit

* nits

* starting to experiment with changelist approach

* an approach to object assignment

* start working with array elements

* saving changes from before break...

* sm formatting pr fb

* ApiView FB per generality of DynamicData

* nits

* small thoughts

* first steps toward abstracting ChangeTracker

* In flight changes while implementing AddPropertyToObject

* adding tests with simple modifications to structural elements

* Implementing WriteTo()

* Added nested objects

* refactor

* missed changes

* In TDD spirit, add failing WriteTo test

* Test passes

* quick refactor

* update add property test

* Update WriteTo to handle property additions at the root element

* Handle property additions on arbitrary objects

* handle standard property removals

* Support Replace with object

* Support Replace with object

* refactor where we serialize structural changes to centralize

* Implement reference semantics for JsonDataElement

* experiment with checking ancestors for structural changes.

* Update WriteTo to handle structural changes.

* add high water mark logic

* add validation to all reads and add failing test for ignoring pre-structural change.

* Incorporate HWM logic in all change lookups; make PriorChangeToReplacedPropertyIsIgnored

* remove double-check of object and array elements

* some tidy up

* Reimplement GetProperty in terms of TryGetProperty()

* Handle WriteTo for structural changes.

* add some tests of structural changes

* refactor tests

* Bug fix to WriteTo for bools and test refactoring

* bug fix to WriteTo for booleans

* Add support for nulls and fix ToLower() bug

* add perf benchmark prior to working on perf

* missed file

* update Parse() to use Memory<byte>

* move subclasses to separate files for ease of reading

* refactor to add dynamic layer

* Add cast operators to JsonDataElement to pass dynamic GetIntProperty test

* Add support for dynamic nested property access

* enable set via dynamic layer

* Enable setting nested properties via dynamic layer

* nit

* Renames prior to dynamic refactor

* start adding separate dynamic layer

* Move dynamic meta object to dyanmic types.

* API updates

* todos and nits

* rename test to match types

* remove outer DynamicJson class

* add BindConvert to dynamic layer

* Add BindGetIndex to dynamic layer

* save multitarget attempt

* Add target frameworks to Experimental to allow ifdefs by target framework.

* PR feedback; use more efficient Deserialize call when available in ConvertTo()

* refactor per PR fb

* Add BindSetIndex to dynamic layer

* Fix bug in mutable ToString() where changes to descendants weren't accounted for

* Fix WriteTo() bug for string elements and add failing test for handling nulls

* Handle null values

* PR fb

* Add support for floats and longs

* remove HasValue, per pr fb

* export API changes

* Support adding properties on dynamic member assignments

* reshuffle methods around

* some changes before adding support for IEnumerable

* Add ArrayEnumerator to MutableJsonElement

* missed file; dynamic portion not complete

* Bug fix to dynamic ArrayEnumerator; foreach over array now passes

* export API and misc test updates

* nit; cleanup

* Make MutableJsonDocument serializable

* Make DynamicJson serializable; enable reference semantics for added properties

* Make tests pass for net6.0 & net7.0; will address net461 separately

* Fixes for some net461 issues

* Fix Add and Set property for net461

* Work around BindBinaryOperation in net461; move inline TODOs to GH issue

* Export API
  • Loading branch information
annelo-msft authored and richardcho-msft committed Feb 6, 2023
1 parent e264784 commit 578adcd
Show file tree
Hide file tree
Showing 17 changed files with 377 additions and 1,516 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,52 +115,89 @@ public static partial class BinaryDataExtensions
public abstract partial class DynamicData
{
protected DynamicData() { }
internal abstract void WriteTo(System.Text.Json.Utf8JsonWriter writer);
public static void WriteTo(System.Text.Json.Utf8JsonWriter writer, Azure.Core.Dynamic.DynamicData data) { }
internal abstract void WriteTo(System.IO.Stream stream);
public static void WriteTo(System.IO.Stream stream, Azure.Core.Dynamic.DynamicData data) { }
}
[System.Diagnostics.DebuggerDisplayAttribute("{DebuggerDisplay,nq}")]
public partial class JsonData : Azure.Core.Dynamic.DynamicData, System.Dynamic.IDynamicMetaObjectProvider, System.IEquatable<Azure.Core.Dynamic.JsonData>
public partial class DynamicJson : Azure.Core.Dynamic.DynamicData, System.Dynamic.IDynamicMetaObjectProvider
{
internal JsonData() { }
public bool Equals(Azure.Core.Dynamic.JsonData other) { throw null; }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, bool right) { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, double right) { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, int right) { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, long right) { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, float right) { throw null; }
public static bool operator ==(Azure.Core.Dynamic.JsonData? left, string? right) { throw null; }
public static bool operator ==(bool left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator ==(double left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator ==(int left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator ==(long left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator ==(float left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator ==(string? left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static implicit operator bool (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator double (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator int (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator long (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator bool? (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator double? (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator int? (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator long? (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator float? (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator float (Azure.Core.Dynamic.JsonData json) { throw null; }
public static implicit operator string (Azure.Core.Dynamic.JsonData json) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, bool right) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, double right) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, int right) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, long right) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, float right) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.JsonData? left, string? right) { throw null; }
public static bool operator !=(bool left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator !=(double left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator !=(int left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator !=(long left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator !=(float left, Azure.Core.Dynamic.JsonData? right) { throw null; }
public static bool operator !=(string? left, Azure.Core.Dynamic.JsonData? right) { throw null; }
internal DynamicJson() { }
public static implicit operator bool (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator double (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator int (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator long (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator bool? (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator double? (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator int? (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator long? (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator float? (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator float (Azure.Core.Dynamic.DynamicJson value) { throw null; }
public static implicit operator string (Azure.Core.Dynamic.DynamicJson value) { throw null; }
System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; }
public override string ToString() { throw null; }
[System.Diagnostics.DebuggerDisplayAttribute("{Current,nq}")]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<Azure.Core.Dynamic.DynamicJson>, System.Collections.Generic.IEnumerator<Azure.Core.Dynamic.DynamicJson>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
{
private object _dummy;
private int _dummyPrimitive;
public Azure.Core.Dynamic.DynamicJson Current { get { throw null; } }
object System.Collections.IEnumerator.Current { get { throw null; } }
public void Dispose() { }
public Azure.Core.Dynamic.DynamicJson.ArrayEnumerator GetEnumerator() { throw null; }
public bool MoveNext() { throw null; }
public void Reset() { }
System.Collections.Generic.IEnumerator<Azure.Core.Dynamic.DynamicJson> System.Collections.Generic.IEnumerable<Azure.Core.Dynamic.DynamicJson>.GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
public partial class MutableJsonDocument
{
internal MutableJsonDocument() { }
public Azure.Core.Dynamic.MutableJsonElement RootElement { get { throw null; } }
public static Azure.Core.Dynamic.MutableJsonDocument Parse(System.BinaryData utf8Json) { throw null; }
public static Azure.Core.Dynamic.MutableJsonDocument Parse(string json) { throw null; }
public void WriteTo(System.IO.Stream stream, System.Buffers.StandardFormat format = default(System.Buffers.StandardFormat)) { }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct MutableJsonElement
{
private object _dummy;
private int _dummyPrimitive;
public System.Text.Json.JsonValueKind ValueKind { get { throw null; } }
public Azure.Core.Dynamic.MutableJsonElement.ArrayEnumerator EnumerateArray() { throw null; }
public bool GetBoolean() { throw null; }
public double GetDouble() { throw null; }
public int GetInt32() { throw null; }
public long GetInt64() { throw null; }
public Azure.Core.Dynamic.MutableJsonElement GetProperty(string name) { throw null; }
public float GetSingle() { throw null; }
public string? GetString() { throw null; }
public void RemoveProperty(string name) { }
public void Set(Azure.Core.Dynamic.MutableJsonElement value) { }
public void Set(bool value) { }
public void Set(double value) { }
public void Set(int value) { }
public void Set(long value) { }
public void Set(object value) { }
public void Set(float value) { }
public void Set(string value) { }
public Azure.Core.Dynamic.MutableJsonElement SetProperty(string name, object value) { throw null; }
public override string ToString() { throw null; }
public bool TryGetProperty(string name, out Azure.Core.Dynamic.MutableJsonElement value) { throw null; }
[System.Diagnostics.DebuggerDisplayAttribute("{Current,nq}")]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<Azure.Core.Dynamic.MutableJsonElement>, System.Collections.Generic.IEnumerator<Azure.Core.Dynamic.MutableJsonElement>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
{
private object _dummy;
private int _dummyPrimitive;
public Azure.Core.Dynamic.MutableJsonElement Current { get { throw null; } }
object System.Collections.IEnumerator.Current { get { throw null; } }
public void Dispose() { }
public Azure.Core.Dynamic.MutableJsonElement.ArrayEnumerator GetEnumerator() { throw null; }
public bool MoveNext() { throw null; }
public void Reset() { }
System.Collections.Generic.IEnumerator<Azure.Core.Dynamic.MutableJsonElement> System.Collections.Generic.IEnumerable<Azure.Core.Dynamic.MutableJsonElement>.GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Experimental types that might eventually move to Azure.Core</Description>
<AssemblyTitle>Microsoft Azure Client Pipeline Experimental Extensions</AssemblyTitle>
<Version>0.1.0-preview.24</Version>
<PackageTags>Microsoft Azure Client Pipeline</PackageTags>
<Nullable>enable</Nullable>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<TargetFrameworks>$(RequiredTargetFrameworks);net461;net6.0</TargetFrameworks>
<NoWarn>$(NoWarn);AZC0001;AZC0012</NoWarn>
<IncludeOperationsSharedSource>true</IncludeOperationsSharedSource>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static class BinaryDataExtensions
/// </summary>
public static dynamic ToDynamic(this BinaryData data)
{
return JsonData.Parse(data);
return new DynamicJson(MutableJsonDocument.Parse(data).RootElement);
}
}
}
12 changes: 6 additions & 6 deletions sdk/core/Azure.Core.Experimental/src/DynamicData.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Text.Json;
using System.IO;

namespace Azure.Core.Dynamic
{
Expand All @@ -14,15 +14,15 @@ namespace Azure.Core.Dynamic
public abstract class DynamicData
{
/// <summary>
/// Writes the data to the provided writer as a JSON value.
/// Writes the data to the provided stream.
/// </summary>
/// <param name="writer">The writer to which to write the document.</param>
/// <param name="stream">The stream to which to write the document.</param>
/// <param name="data">The dynamic data value to write.</param>
public static void WriteTo(Utf8JsonWriter writer, DynamicData data)
public static void WriteTo(Stream stream, DynamicData data)
{
data.WriteTo(writer);
data.WriteTo(stream);
}

internal abstract void WriteTo(Utf8JsonWriter writer);
internal abstract void WriteTo(Stream stream);
}
}
Loading

0 comments on commit 578adcd

Please sign in to comment.