|  | @@ -19,8 +19,56 @@ using System;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  namespace Google.ProtocolBuffers {
 | 
	
		
			
				|  |  |    /// <summary>
 | 
	
		
			
				|  |  | -  /// TODO(jonskeet): Copy docs from Java
 | 
	
		
			
				|  |  | +  /// A table of known extensions, searchable by name or field number.  When
 | 
	
		
			
				|  |  | +  /// parsing a protocol message that might have extensions, you must provide
 | 
	
		
			
				|  |  | +  /// an <see cref="ExtensionRegistry"/> in which you have registered any extensions
 | 
	
		
			
				|  |  | +  /// that you want to be able to parse.  Otherwise, those extensions will just
 | 
	
		
			
				|  |  | +  /// be treated like unknown fields.
 | 
	
		
			
				|  |  |    /// </summary>
 | 
	
		
			
				|  |  | +  /// <example>
 | 
	
		
			
				|  |  | +  /// For example, if you had the <c>.proto</c> file:
 | 
	
		
			
				|  |  | +  /// <code>
 | 
	
		
			
				|  |  | +  /// option java_class = "MyProto";
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// message Foo {
 | 
	
		
			
				|  |  | +  ///   extensions 1000 to max;
 | 
	
		
			
				|  |  | +  /// }
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// extend Foo {
 | 
	
		
			
				|  |  | +  ///   optional int32 bar;
 | 
	
		
			
				|  |  | +  /// }
 | 
	
		
			
				|  |  | +  /// </code>
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// Then you might write code like:
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// <code>
 | 
	
		
			
				|  |  | +  /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
 | 
	
		
			
				|  |  | +  /// registry.Add(MyProto.Bar);
 | 
	
		
			
				|  |  | +  /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry);
 | 
	
		
			
				|  |  | +  /// </code>
 | 
	
		
			
				|  |  | +  /// </example>
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// <remarks>
 | 
	
		
			
				|  |  | +  /// <para>You might wonder why this is necessary. Two alternatives might come to
 | 
	
		
			
				|  |  | +  /// mind. First, you might imagine a system where generated extensions are
 | 
	
		
			
				|  |  | +  /// automatically registered when their containing classes are loaded. This
 | 
	
		
			
				|  |  | +  /// is a popular technique, but is bad design; among other things, it creates a
 | 
	
		
			
				|  |  | +  /// situation where behavior can change depending on what classes happen to be
 | 
	
		
			
				|  |  | +  /// loaded. It also introduces a security vulnerability, because an
 | 
	
		
			
				|  |  | +  /// unprivileged class could cause its code to be called unexpectedly from a
 | 
	
		
			
				|  |  | +  /// privileged class by registering itself as an extension of the right type.
 | 
	
		
			
				|  |  | +  /// </para>
 | 
	
		
			
				|  |  | +  /// <para>Another option you might consider is lazy parsing: do not parse an
 | 
	
		
			
				|  |  | +  /// extension until it is first requested, at which point the caller must
 | 
	
		
			
				|  |  | +  /// provide a type to use. This introduces a different set of problems. First,
 | 
	
		
			
				|  |  | +  /// it would require a mutex lock any time an extension was accessed, which
 | 
	
		
			
				|  |  | +  /// would be slow. Second, corrupt data would not be detected until first
 | 
	
		
			
				|  |  | +  /// access, at which point it would be much harder to deal with it. Third, it
 | 
	
		
			
				|  |  | +  /// could violate the expectation that message objects are immutable, since the
 | 
	
		
			
				|  |  | +  /// type provided could be any arbitrary message class. An unprivileged user
 | 
	
		
			
				|  |  | +  /// could take advantage of this to inject a mutable object into a message
 | 
	
		
			
				|  |  | +  /// belonging to privileged code and create mischief.</para>
 | 
	
		
			
				|  |  | +  /// </remarks>
 | 
	
		
			
				|  |  |    public sealed class ExtensionRegistry {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private static readonly ExtensionRegistry empty = new ExtensionRegistry(
 | 
	
	
		
			
				|  | @@ -140,7 +188,7 @@ namespace Google.ProtocolBuffers {
 | 
	
		
			
				|  |  |            && field.IsOptional
 | 
	
		
			
				|  |  |            && field.ExtensionScope == field.MessageType) {
 | 
	
		
			
				|  |  |          // This is an extension of a MessageSet type defined within the extension
 | 
	
		
			
				|  |  | -        // type's own scope.  For backwards-compatibility, allow it to be looked
 | 
	
		
			
				|  |  | +        // type's own scope. For backwards-compatibility, allow it to be looked
 | 
	
		
			
				|  |  |          // up by type name.
 | 
	
		
			
				|  |  |          extensionsByName[field.MessageType.FullName] = extension;
 | 
	
		
			
				|  |  |        }
 |