/// <summary> /// Parses a single field from the specified tokenizer and merges it into /// the builder. /// </summary> private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry, IBuilder builder) { FieldDescriptor field; MessageDescriptor type = builder.DescriptorForType; ExtensionInfo extension = null; if (tokenizer.TryConsume("[")) { // An extension. StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier()); while (tokenizer.TryConsume(".")) { name.Append("."); name.Append(tokenizer.ConsumeIdentifier()); } extension = extensionRegistry.FindByName(type, name.ToString()); if (extension == null) { throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" not found in the ExtensionRegistry."); } else if (extension.Descriptor.ContainingType != type) { throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" does not extend message type \"" + type.FullName + "\"."); } tokenizer.Consume("]"); field = extension.Descriptor; } else { String name = tokenizer.ConsumeIdentifier(); field = type.FindDescriptor <FieldDescriptor>(name); // Group names are expected to be capitalized as they appear in the // .proto file, which actually matches their type names, not their field // names. if (field == null) { // Explicitly specify the invariant culture so that this code does not break when // executing in Turkey. #if PORTABLE_LIBRARY String lowerName = name.ToLowerInvariant(); #else String lowerName = name.ToLower(FrameworkPortability.InvariantCulture); #endif field = type.FindDescriptor <FieldDescriptor>(lowerName); // If the case-insensitive match worked but the field is NOT a group, // TODO(jonskeet): What? Java comment ends here! if (field != null && field.FieldType != FieldType.Group) { field = null; } } // Again, special-case group names as described above. if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) { field = null; } if (field == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Message type \"" + type.FullName + "\" has no field named \"" + name + "\"."); } } object value = null; if (field.MappedType == MappedType.Message) { tokenizer.TryConsume(":"); // optional String endToken; if (tokenizer.TryConsume("<")) { endToken = ">"; } else { tokenizer.Consume("{"); endToken = "}"; } IBuilder subBuilder; if (extension == null) { subBuilder = builder.CreateBuilderForField(field); } else { subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder; if (subBuilder == null) { throw new NotSupportedException("Lite messages are not supported."); } } while (!tokenizer.TryConsume(endToken)) { if (tokenizer.AtEnd) { throw tokenizer.CreateFormatException("Expected \"" + endToken + "\"."); } MergeField(tokenizer, extensionRegistry, subBuilder); } value = subBuilder.WeakBuild(); } else { tokenizer.Consume(":"); switch (field.FieldType) { case FieldType.Int32: case FieldType.SInt32: case FieldType.SFixed32: value = tokenizer.ConsumeInt32(); break; case FieldType.Int64: case FieldType.SInt64: case FieldType.SFixed64: value = tokenizer.ConsumeInt64(); break; case FieldType.UInt32: case FieldType.Fixed32: value = tokenizer.ConsumeUInt32(); break; case FieldType.UInt64: case FieldType.Fixed64: value = tokenizer.ConsumeUInt64(); break; case FieldType.Float: value = tokenizer.ConsumeFloat(); break; case FieldType.Double: value = tokenizer.ConsumeDouble(); break; case FieldType.Bool: value = tokenizer.ConsumeBoolean(); break; case FieldType.String: value = tokenizer.ConsumeString(); break; case FieldType.Bytes: value = tokenizer.ConsumeByteString(); break; case FieldType.Enum: { EnumDescriptor enumType = field.EnumType; if (tokenizer.LookingAtInteger()) { int number = tokenizer.ConsumeInt32(); value = enumType.FindValueByNumber(number); if (value == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Enum type \"" + enumType.FullName + "\" has no value with number " + number + "."); } } else { String id = tokenizer.ConsumeIdentifier(); value = enumType.FindValueByName(id); if (value == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Enum type \"" + enumType.FullName + "\" has no value named \"" + id + "\"."); } } break; } case FieldType.Message: case FieldType.Group: throw new InvalidOperationException("Can't get here."); } } if (field.IsRepeated) { builder.WeakAddRepeatedField(field, value); } else { builder.SetField(field, value); } }
/// <summary> /// Parses a single field from the specified tokenizer and merges it into /// the builder. /// </summary> private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry, IBuilder builder) { FieldDescriptor field; MessageDescriptor type = builder.DescriptorForType; ExtensionInfo extension = null; if (tokenizer.TryConsume("[")) { // An extension. StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier()); while (tokenizer.TryConsume(".")) { name.Append("."); name.Append(tokenizer.ConsumeIdentifier()); } extension = extensionRegistry.FindByName(type, name.ToString()); if (extension == null) { throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" not found in the ExtensionRegistry."); } else if (extension.Descriptor.ContainingType != type) { throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name + "\" does not extend message type \"" + type.FullName + "\"."); } tokenizer.Consume("]"); field = extension.Descriptor; } else { String name = tokenizer.ConsumeIdentifier(); field = type.FindDescriptor<FieldDescriptor>(name); // Group names are expected to be capitalized as they appear in the // .proto file, which actually matches their type names, not their field // names. if (field == null) { // Explicitly specify the invariant culture so that this code does not break when // executing in Turkey. String lowerName = name.ToLowerInvariant(); field = type.FindDescriptor<FieldDescriptor>(lowerName); // If the case-insensitive match worked but the field is NOT a group, // TODO(jonskeet): What? Java comment ends here! if (field != null && field.FieldType != FieldType.Group) { field = null; } } // Again, special-case group names as described above. if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name) { field = null; } if (field == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Message type \"" + type.FullName + "\" has no field named \"" + name + "\"."); } } object value = null; if (field.MappedType == MappedType.Message) { tokenizer.TryConsume(":"); // optional String endToken; if (tokenizer.TryConsume("<")) { endToken = ">"; } else { tokenizer.Consume("{"); endToken = "}"; } IBuilder subBuilder; if (extension == null) { subBuilder = builder.CreateBuilderForField(field); } else { subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder; if (subBuilder == null) { throw new NotSupportedException("Lite messages are not supported."); } } while (!tokenizer.TryConsume(endToken)) { if (tokenizer.AtEnd) { throw tokenizer.CreateFormatException("Expected \"" + endToken + "\"."); } MergeField(tokenizer, extensionRegistry, subBuilder); } value = subBuilder.WeakBuild(); } else { tokenizer.Consume(":"); switch (field.FieldType) { case FieldType.Int32: case FieldType.SInt32: case FieldType.SFixed32: value = tokenizer.ConsumeInt32(); break; case FieldType.Int64: case FieldType.SInt64: case FieldType.SFixed64: value = tokenizer.ConsumeInt64(); break; case FieldType.UInt32: case FieldType.Fixed32: value = tokenizer.ConsumeUInt32(); break; case FieldType.UInt64: case FieldType.Fixed64: value = tokenizer.ConsumeUInt64(); break; case FieldType.Float: value = tokenizer.ConsumeFloat(); break; case FieldType.Double: value = tokenizer.ConsumeDouble(); break; case FieldType.Bool: value = tokenizer.ConsumeBoolean(); break; case FieldType.String: value = tokenizer.ConsumeString(); break; case FieldType.Bytes: value = tokenizer.ConsumeByteString(); break; case FieldType.Enum: { EnumDescriptor enumType = field.EnumType; if (tokenizer.LookingAtInteger()) { int number = tokenizer.ConsumeInt32(); value = enumType.FindValueByNumber(number); if (value == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Enum type \"" + enumType.FullName + "\" has no value with number " + number + "."); } } else { String id = tokenizer.ConsumeIdentifier(); value = enumType.FindValueByName(id); if (value == null) { throw tokenizer.CreateFormatExceptionPreviousToken( "Enum type \"" + enumType.FullName + "\" has no value named \"" + id + "\"."); } } break; } case FieldType.Message: case FieldType.Group: throw new InvalidOperationException("Can't get here."); } } if (field.IsRepeated) { builder.WeakAddRepeatedField(field, value); } else { builder.SetField(field, value); } }
/// <summary> /// Read a double field from the stream. /// </summary> public bool ReadDouble(ref double value) { tokenizer.Consume(":"); value = tokenizer.ConsumeDouble(); return(true); }