using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; namespace Google.Protobuf { // Token: 0x0200000F RID: 15 public sealed class JsonFormatter { // Token: 0x17000015 RID: 21 // (get) Token: 0x060000D4 RID: 212 RVA: 0x00004564 File Offset: 0x00002764 public static JsonFormatter Default { get; } = new JsonFormatter(JsonFormatter.Settings.Default); // Token: 0x060000D5 RID: 213 RVA: 0x0000456C File Offset: 0x0000276C static JsonFormatter() { for (int i = 0; i < JsonFormatter.CommonRepresentations.Length; i++) { if (JsonFormatter.CommonRepresentations[i] == "") { JsonFormatter.CommonRepresentations[i] = ((char)i).ToString(); } } } // Token: 0x17000016 RID: 22 // (get) Token: 0x060000D6 RID: 214 RVA: 0x00004BD3 File Offset: 0x00002DD3 private bool DiagnosticOnly { get { return this == JsonFormatter.diagnosticFormatter; } } // Token: 0x060000D7 RID: 215 RVA: 0x00004BDD File Offset: 0x00002DDD public JsonFormatter(JsonFormatter.Settings settings) { this.settings = settings; } // Token: 0x060000D8 RID: 216 RVA: 0x00004BEC File Offset: 0x00002DEC public string Format(IMessage message) { StringWriter stringWriter = new StringWriter(); this.Format(message, stringWriter); return stringWriter.ToString(); } // Token: 0x060000D9 RID: 217 RVA: 0x00004C0D File Offset: 0x00002E0D public void Format(IMessage message, TextWriter writer) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(writer, "writer"); if (message.Descriptor.IsWellKnownType) { this.WriteWellKnownTypeValue(writer, message.Descriptor, message); return; } this.WriteMessage(writer, message); } // Token: 0x060000DA RID: 218 RVA: 0x00004C4B File Offset: 0x00002E4B public static string ToDiagnosticString(IMessage message) { ProtoPreconditions.CheckNotNull(message, "message"); return JsonFormatter.diagnosticFormatter.Format(message); } // Token: 0x060000DB RID: 219 RVA: 0x00004C64 File Offset: 0x00002E64 private void WriteMessage(TextWriter writer, IMessage message) { if (message == null) { JsonFormatter.WriteNull(writer); return; } if (this.DiagnosticOnly) { ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage; if (customDiagnosticMessage != null) { writer.Write(customDiagnosticMessage.ToDiagnosticString()); return; } } writer.Write("{ "); writer.Write(this.WriteMessageFields(writer, message, false) ? " }" : "}"); } // Token: 0x060000DC RID: 220 RVA: 0x00004CC4 File Offset: 0x00002EC4 private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten) { MessageDescriptor.FieldCollection fields = message.Descriptor.Fields; bool flag = !assumeFirstFieldWritten; foreach (FieldDescriptor fieldDescriptor in fields.InFieldNumberOrder()) { IFieldAccessor accessor = fieldDescriptor.Accessor; if (fieldDescriptor.ContainingOneof == null || fieldDescriptor.ContainingOneof.Accessor.GetCaseFieldDescriptor(message) == fieldDescriptor) { object value = accessor.GetValue(message); if (fieldDescriptor.ContainingOneof != null || this.settings.FormatDefaultValues || !JsonFormatter.IsDefaultValue(accessor, value)) { if (!flag) { writer.Write(", "); } JsonFormatter.WriteString(writer, accessor.Descriptor.JsonName); writer.Write(": "); this.WriteValue(writer, value); flag = false; } } } return !flag; } // Token: 0x060000DD RID: 221 RVA: 0x00004DA4 File Offset: 0x00002FA4 private static string ToCamelCaseForFieldMask(string input) { for (int i = 0; i < input.Length; i++) { char c = input[i]; if (c >= 'A' && c <= 'Z') { throw new InvalidOperationException(string.Format("Invalid field mask to be converted to JSON: {0}", input)); } if (c == '_' && i < input.Length - 1) { char c2 = input[i + 1]; if (c2 < 'a' || c2 > 'z') { throw new InvalidOperationException(string.Format("Invalid field mask to be converted to JSON: {0}", input)); } } } return JsonFormatter.ToCamelCase(input); } // Token: 0x060000DE RID: 222 RVA: 0x00004E20 File Offset: 0x00003020 internal static string ToCamelCase(string input) { bool flag = false; bool flag2 = true; bool flag3 = true; StringBuilder stringBuilder = new StringBuilder(input.Length); int i = 0; while (i < input.Length) { bool flag4 = char.IsUpper(input[i]); if (input[i] == '_') { flag = true; if (stringBuilder.Length != 0) { flag3 = false; } } else if (flag3) { if (stringBuilder.Length != 0 && flag4 && (!flag2 || (i + 1 < input.Length && char.IsLower(input[i + 1])))) { flag3 = false; stringBuilder.Append(input[i]); } else { stringBuilder.Append(char.ToLowerInvariant(input[i])); } } else if (flag) { flag = false; if (char.IsLower(input[i])) { stringBuilder.Append(char.ToUpperInvariant(input[i])); } else { stringBuilder.Append(input[i]); } } else { stringBuilder.Append(char.ToLowerInvariant(input[i])); } i++; flag2 = flag4; } return stringBuilder.ToString(); } // Token: 0x060000DF RID: 223 RVA: 0x00004F43 File Offset: 0x00003143 private static void WriteNull(TextWriter writer) { writer.Write("null"); } // Token: 0x060000E0 RID: 224 RVA: 0x00004F50 File Offset: 0x00003150 private static bool IsDefaultValue(IFieldAccessor accessor, object value) { if (accessor.Descriptor.IsMap) { return ((IDictionary)value).Count == 0; } if (accessor.Descriptor.IsRepeated) { return ((IList)value).Count == 0; } switch (accessor.Descriptor.FieldType) { case FieldType.Double: return (double)value == 0.0; case FieldType.Float: return (float)value == 0f; case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: return (long)value == 0L; case FieldType.UInt64: case FieldType.Fixed64: return (ulong)value == 0UL; case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: case FieldType.Enum: return (int)value == 0; case FieldType.Fixed32: case FieldType.UInt32: return (uint)value == 0U; case FieldType.Bool: return !(bool)value; case FieldType.String: return (string)value == ""; case FieldType.Group: case FieldType.Message: return value == null; case FieldType.Bytes: return (ByteString)value == ByteString.Empty; default: throw new ArgumentException("Invalid field type"); } } // Token: 0x060000E1 RID: 225 RVA: 0x00005078 File Offset: 0x00003278 public void WriteValue(TextWriter writer, object value) { if (value == null) { JsonFormatter.WriteNull(writer); return; } if (value is bool) { writer.Write(((bool)value) ? "true" : "false"); return; } if (value is ByteString) { writer.Write('"'); writer.Write(((ByteString)value).ToBase64()); writer.Write('"'); return; } if (value is string) { JsonFormatter.WriteString(writer, (string)value); return; } if (value is IDictionary) { this.WriteDictionary(writer, (IDictionary)value); return; } if (value is IList) { this.WriteList(writer, (IList)value); return; } if (value is int || value is uint) { IFormattable formattable = (IFormattable)value; writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture)); return; } if (value is long || value is ulong) { writer.Write('"'); IFormattable formattable2 = (IFormattable)value; writer.Write(formattable2.ToString("d", CultureInfo.InvariantCulture)); writer.Write('"'); return; } if (value is global::System.Enum) { string originalName = JsonFormatter.OriginalEnumValueHelper.GetOriginalName(value); if (originalName != null) { JsonFormatter.WriteString(writer, originalName); return; } this.WriteValue(writer, (int)value); return; } else if (value is float || value is double) { string text = ((IFormattable)value).ToString("r", CultureInfo.InvariantCulture); if (text == "NaN" || text == "Infinity" || text == "-Infinity") { writer.Write('"'); writer.Write(text); writer.Write('"'); return; } writer.Write(text); return; } else { if (value is IMessage) { this.Format((IMessage)value, writer); return; } throw new ArgumentException("Unable to format value of type " + value.GetType()); } } // Token: 0x060000E2 RID: 226 RVA: 0x00005250 File Offset: 0x00003450 private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value) { if (value == null) { JsonFormatter.WriteNull(writer); return; } if (descriptor.IsWrapperType) { if (value is IMessage) { IMessage message = (IMessage)value; value = message.Descriptor.Fields[1].Accessor.GetValue(message); } this.WriteValue(writer, value); return; } if (descriptor.FullName == Timestamp.Descriptor.FullName) { this.WriteTimestamp(writer, (IMessage)value); return; } if (descriptor.FullName == Duration.Descriptor.FullName) { this.WriteDuration(writer, (IMessage)value); return; } if (descriptor.FullName == FieldMask.Descriptor.FullName) { this.WriteFieldMask(writer, (IMessage)value); return; } if (descriptor.FullName == Struct.Descriptor.FullName) { this.WriteStruct(writer, (IMessage)value); return; } if (descriptor.FullName == ListValue.Descriptor.FullName) { IFieldAccessor accessor = descriptor.Fields[1].Accessor; this.WriteList(writer, (IList)accessor.GetValue((IMessage)value)); return; } if (descriptor.FullName == Value.Descriptor.FullName) { this.WriteStructFieldValue(writer, (IMessage)value); return; } if (descriptor.FullName == Any.Descriptor.FullName) { this.WriteAny(writer, (IMessage)value); return; } this.WriteMessage(writer, (IMessage)value); } // Token: 0x060000E3 RID: 227 RVA: 0x000053D4 File Offset: 0x000035D4 private void WriteTimestamp(TextWriter writer, IMessage value) { int num = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long num2 = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Timestamp.ToJson(num2, num, this.DiagnosticOnly)); } // Token: 0x060000E4 RID: 228 RVA: 0x00005438 File Offset: 0x00003638 private void WriteDuration(TextWriter writer, IMessage value) { int num = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long num2 = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Duration.ToJson(num2, num, this.DiagnosticOnly)); } // Token: 0x060000E5 RID: 229 RVA: 0x0000549C File Offset: 0x0000369C private void WriteFieldMask(TextWriter writer, IMessage value) { IList list = (IList)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(FieldMask.ToJson(list, this.DiagnosticOnly)); } // Token: 0x060000E6 RID: 230 RVA: 0x000054E0 File Offset: 0x000036E0 private void WriteAny(TextWriter writer, IMessage value) { if (this.DiagnosticOnly) { this.WriteDiagnosticOnlyAny(writer, value); return; } string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString byteString = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); string typeName = Any.GetTypeName(text); MessageDescriptor messageDescriptor = this.settings.TypeRegistry.Find(typeName); if (messageDescriptor == null) { throw new InvalidOperationException(string.Format("Type registry has no descriptor for type name '{0}'", typeName)); } IMessage message = messageDescriptor.Parser.ParseFrom(byteString); writer.Write("{ "); JsonFormatter.WriteString(writer, "@type"); writer.Write(": "); JsonFormatter.WriteString(writer, text); if (messageDescriptor.IsWellKnownType) { writer.Write(", "); JsonFormatter.WriteString(writer, "value"); writer.Write(": "); this.WriteWellKnownTypeValue(writer, messageDescriptor, message); } else { this.WriteMessageFields(writer, message, true); } writer.Write(" }"); } // Token: 0x060000E7 RID: 231 RVA: 0x000055F0 File Offset: 0x000037F0 private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value) { string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString byteString = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); writer.Write("{ "); JsonFormatter.WriteString(writer, "@type"); writer.Write(": "); JsonFormatter.WriteString(writer, text); writer.Write(", "); JsonFormatter.WriteString(writer, "@value"); writer.Write(": "); writer.Write('"'); writer.Write(byteString.ToBase64()); writer.Write('"'); writer.Write(" }"); } // Token: 0x060000E8 RID: 232 RVA: 0x000056B4 File Offset: 0x000038B4 private void WriteStruct(TextWriter writer, IMessage message) { writer.Write("{ "); IDictionary dictionary = (IDictionary)message.Descriptor.Fields[1].Accessor.GetValue(message); bool flag = true; foreach (object obj in dictionary) { DictionaryEntry dictionaryEntry = (DictionaryEntry)obj; string text = (string)dictionaryEntry.Key; IMessage message2 = (IMessage)dictionaryEntry.Value; if (string.IsNullOrEmpty(text) || message2 == null) { throw new InvalidOperationException("Struct fields cannot have an empty key or a null value."); } if (!flag) { writer.Write(", "); } JsonFormatter.WriteString(writer, text); writer.Write(": "); this.WriteStructFieldValue(writer, message2); flag = false; } writer.Write(flag ? "}" : " }"); } // Token: 0x060000E9 RID: 233 RVA: 0x000057A4 File Offset: 0x000039A4 private void WriteStructFieldValue(TextWriter writer, IMessage message) { FieldDescriptor caseFieldDescriptor = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message); if (caseFieldDescriptor == null) { throw new InvalidOperationException("Value message must contain a value for the oneof."); } object value = caseFieldDescriptor.Accessor.GetValue(message); switch (caseFieldDescriptor.FieldNumber) { case 1: JsonFormatter.WriteNull(writer); return; case 2: case 3: case 4: this.WriteValue(writer, value); return; case 5: case 6: { IMessage message2 = (IMessage)caseFieldDescriptor.Accessor.GetValue(message); this.WriteWellKnownTypeValue(writer, message2.Descriptor, message2); return; } default: throw new InvalidOperationException("Unexpected case in struct field: " + caseFieldDescriptor.FieldNumber); } } // Token: 0x060000EA RID: 234 RVA: 0x00005860 File Offset: 0x00003A60 internal void WriteList(TextWriter writer, IList list) { writer.Write("[ "); bool flag = true; foreach (object obj in list) { if (!flag) { writer.Write(", "); } this.WriteValue(writer, obj); flag = false; } writer.Write(flag ? "]" : " ]"); } // Token: 0x060000EB RID: 235 RVA: 0x000058E4 File Offset: 0x00003AE4 internal void WriteDictionary(TextWriter writer, IDictionary dictionary) { writer.Write("{ "); bool flag = true; foreach (object obj in dictionary) { DictionaryEntry dictionaryEntry = (DictionaryEntry)obj; if (!flag) { writer.Write(", "); } string text; if (dictionaryEntry.Key is string) { text = (string)dictionaryEntry.Key; } else if (dictionaryEntry.Key is bool) { text = (((bool)dictionaryEntry.Key) ? "true" : "false"); } else if (dictionaryEntry.Key is int || ((dictionaryEntry.Key is uint) | (dictionaryEntry.Key is long)) || dictionaryEntry.Key is ulong) { text = ((IFormattable)dictionaryEntry.Key).ToString("d", CultureInfo.InvariantCulture); } else { if (dictionaryEntry.Key == null) { throw new ArgumentException("Dictionary has entry with null key"); } throw new ArgumentException("Unhandled dictionary key type: " + dictionaryEntry.Key.GetType()); } JsonFormatter.WriteString(writer, text); writer.Write(": "); this.WriteValue(writer, dictionaryEntry.Value); flag = false; } writer.Write(flag ? "}" : " }"); } // Token: 0x060000EC RID: 236 RVA: 0x00005A74 File Offset: 0x00003C74 internal static void WriteString(TextWriter writer, string text) { writer.Write('"'); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c < '\u00a0') { writer.Write(JsonFormatter.CommonRepresentations[(int)c]); } else if (char.IsHighSurrogate(c)) { i++; if (i == text.Length || !char.IsLowSurrogate(text[i])) { throw new ArgumentException("String contains low surrogate not followed by high surrogate"); } JsonFormatter.HexEncodeUtf16CodeUnit(writer, c); JsonFormatter.HexEncodeUtf16CodeUnit(writer, text[i]); } else { if (char.IsLowSurrogate(c)) { throw new ArgumentException("String contains high surrogate not preceded by low surrogate"); } uint num = (uint)c; if (num <= 1807U) { if (num != 173U && num != 1757U && num != 1807U) { goto IL_D4; } } else if (num - 6068U > 1U && num != 65279U && num - 65529U > 2U) { goto IL_D4; } JsonFormatter.HexEncodeUtf16CodeUnit(writer, c); goto IL_134; IL_D4: if ((c >= '\u0600' && c <= '\u0603') || (c >= '\u200b' && c <= '\u200f') || (c >= '\u2028' && c <= '\u202e') || (c >= '\u2060' && c <= '\u2064') || (c >= '\u206a' && c <= '\u206f')) { JsonFormatter.HexEncodeUtf16CodeUnit(writer, c); } else { writer.Write(c); } } IL_134:; } writer.Write('"'); } // Token: 0x060000ED RID: 237 RVA: 0x00005BD0 File Offset: 0x00003DD0 private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c) { writer.Write("\\u"); writer.Write("0123456789abcdef"[(int)((c >> 12) & '\u000f')]); writer.Write("0123456789abcdef"[(int)((c >> 8) & '\u000f')]); writer.Write("0123456789abcdef"[(int)((c >> 4) & '\u000f')]); writer.Write("0123456789abcdef"[(int)(c & '\u000f')]); } // Token: 0x04000029 RID: 41 internal const string AnyTypeUrlField = "@type"; // Token: 0x0400002A RID: 42 internal const string AnyDiagnosticValueField = "@value"; // Token: 0x0400002B RID: 43 internal const string AnyWellKnownTypeValueField = "value"; // Token: 0x0400002C RID: 44 private const string TypeUrlPrefix = "type.googleapis.com"; // Token: 0x0400002D RID: 45 private const string NameValueSeparator = ": "; // Token: 0x0400002E RID: 46 private const string PropertySeparator = ", "; // Token: 0x04000030 RID: 48 private static readonly JsonFormatter diagnosticFormatter = new JsonFormatter(JsonFormatter.Settings.Default); // Token: 0x04000031 RID: 49 private static readonly string[] CommonRepresentations = new string[] { "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", "", "", "\\\"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u003c", "", "\\u003e", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\\\", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u007f", "\\u0080", "\\u0081", "\\u0082", "\\u0083", "\\u0084", "\\u0085", "\\u0086", "\\u0087", "\\u0088", "\\u0089", "\\u008a", "\\u008b", "\\u008c", "\\u008d", "\\u008e", "\\u008f", "\\u0090", "\\u0091", "\\u0092", "\\u0093", "\\u0094", "\\u0095", "\\u0096", "\\u0097", "\\u0098", "\\u0099", "\\u009a", "\\u009b", "\\u009c", "\\u009d", "\\u009e", "\\u009f" }; // Token: 0x04000032 RID: 50 private readonly JsonFormatter.Settings settings; // Token: 0x04000033 RID: 51 private const string Hex = "0123456789abcdef"; // Token: 0x0200007D RID: 125 public sealed class Settings { // Token: 0x170001CC RID: 460 // (get) Token: 0x060006AB RID: 1707 RVA: 0x0001666F File Offset: 0x0001486F public static JsonFormatter.Settings Default { get; } = new JsonFormatter.Settings(false); // Token: 0x170001CD RID: 461 // (get) Token: 0x060006AD RID: 1709 RVA: 0x00016683 File Offset: 0x00014883 public bool FormatDefaultValues { get; } // Token: 0x170001CE RID: 462 // (get) Token: 0x060006AE RID: 1710 RVA: 0x0001668B File Offset: 0x0001488B public TypeRegistry TypeRegistry { get; } // Token: 0x060006AF RID: 1711 RVA: 0x00016693 File Offset: 0x00014893 public Settings(bool formatDefaultValues) : this(formatDefaultValues, TypeRegistry.Empty) { } // Token: 0x060006B0 RID: 1712 RVA: 0x000166A1 File Offset: 0x000148A1 public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) { this.FormatDefaultValues = formatDefaultValues; this.TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, "typeRegistry"); } } // Token: 0x0200007E RID: 126 private static class OriginalEnumValueHelper { // Token: 0x060006B1 RID: 1713 RVA: 0x000166C4 File Offset: 0x000148C4 internal static string GetOriginalName(object value) { global::System.Type type = value.GetType(); Dictionary> dictionary = JsonFormatter.OriginalEnumValueHelper.dictionaries; Dictionary nameMapping; lock (dictionary) { if (!JsonFormatter.OriginalEnumValueHelper.dictionaries.TryGetValue(type, out nameMapping)) { nameMapping = JsonFormatter.OriginalEnumValueHelper.GetNameMapping(type); JsonFormatter.OriginalEnumValueHelper.dictionaries[type] = nameMapping; } } string text; nameMapping.TryGetValue(value, out text); return text; } // Token: 0x060006B2 RID: 1714 RVA: 0x0001672C File Offset: 0x0001492C private static Dictionary GetNameMapping(global::System.Type enumType) { return enumType.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).ToDictionary((FieldInfo f) => f.GetValue(null), delegate(FieldInfo f) { OriginalNameAttribute originalNameAttribute = f.GetCustomAttributes(typeof(OriginalNameAttribute), false).FirstOrDefault() as OriginalNameAttribute; return ((originalNameAttribute != null) ? originalNameAttribute.Name : null) ?? f.Name; }); } // Token: 0x0400029A RID: 666 private static readonly Dictionary> dictionaries = new Dictionary>(); } } }