|  | @@ -30,62 +30,57 @@
 | 
	
		
			
				|  |  |  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
	
		
			
				|  |  |  #endregion
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +using Google.Protobuf.Descriptors;
 | 
	
		
			
				|  |  | +using System;
 | 
	
		
			
				|  |  | +using System.Reflection;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  namespace Google.Protobuf.FieldAccess
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    // TODO(jonskeet): Add "new" oneof API support
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      /// <summary>
 | 
	
		
			
				|  |  | -    /// Access for an oneof
 | 
	
		
			
				|  |  | +    /// Reflection access for a oneof, allowing clear and "get case" actions.
 | 
	
		
			
				|  |  |      /// </summary>
 | 
	
		
			
				|  |  | -    internal class OneofAccessor<TMessage> where TMessage : IMessage<TMessage>
 | 
	
		
			
				|  |  | +    public sealed class OneofAccessor
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        /*
 | 
	
		
			
				|  |  | -        private readonly Func<TMessage, object> caseDelegate;
 | 
	
		
			
				|  |  | -        private readonly Func<TBuilder, IBuilder> clearDelegate;
 | 
	
		
			
				|  |  | -        private MessageDescriptor descriptor;
 | 
	
		
			
				|  |  | +        private readonly Func<object, int> caseDelegate;
 | 
	
		
			
				|  |  | +        private readonly Action<object> clearDelegate;
 | 
	
		
			
				|  |  | +        private OneofDescriptor descriptor;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        internal OneofAccessor(MessageDescriptor descriptor, string name) 
 | 
	
		
			
				|  |  | +        internal OneofAccessor(Type type, string propertyName, OneofDescriptor descriptor) 
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            this.descriptor = descriptor;
 | 
	
		
			
				|  |  | -            MethodInfo clearMethod = typeof(TBuilder).GetMethod("Clear" + name);
 | 
	
		
			
				|  |  | -            PropertyInfo caseProperty = typeof(TMessage).GetProperty(name + "Case");
 | 
	
		
			
				|  |  | -            if (clearMethod == null || caseProperty == null)
 | 
	
		
			
				|  |  | +            PropertyInfo property = type.GetProperty(propertyName + "Case");
 | 
	
		
			
				|  |  | +            if (property == null || !property.CanRead)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                throw new ArgumentException("Not all required properties/methods available for oneof");
 | 
	
		
			
				|  |  | +                throw new ArgumentException("Not all required properties/methods available");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | +            this.descriptor = descriptor;
 | 
	
		
			
				|  |  | +            caseDelegate = ReflectionUtil.CreateFuncObjectT<int>(property.GetGetMethod());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            clearDelegate = ReflectionUtil.CreateDelegateFunc<TBuilder, IBuilder>(clearMethod);
 | 
	
		
			
				|  |  | -            caseDelegate = ReflectionUtil.CreateUpcastDelegate<TMessage>(caseProperty.GetGetMethod());
 | 
	
		
			
				|  |  | +            this.descriptor = descriptor;
 | 
	
		
			
				|  |  | +            MethodInfo clearMethod = type.GetMethod("Clear" + propertyName);
 | 
	
		
			
				|  |  | +            clearDelegate = ReflectionUtil.CreateActionObject(clearMethod);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        /// <summary>
 | 
	
		
			
				|  |  | -        /// Indicates whether the specified message has set any field in the oneof.
 | 
	
		
			
				|  |  | -        /// </summary>
 | 
	
		
			
				|  |  | -        public bool Has(TMessage message)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return ((int) caseDelegate(message) != 0);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        public OneofDescriptor Descriptor { get { return descriptor; } }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  | -        /// Clears the oneof in the specified builder.
 | 
	
		
			
				|  |  | +        /// Clears the oneof in the specified message.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | -        public void Clear(TBuilder builder)
 | 
	
		
			
				|  |  | +        public void Clear(object message)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            clearDelegate(builder);
 | 
	
		
			
				|  |  | +            clearDelegate(message);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Indicates which field in the oneof is set for specified message
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | -        public virtual FieldDescriptor GetOneofFieldDescriptor(TMessage message)
 | 
	
		
			
				|  |  | +        public FieldDescriptor GetCaseFieldDescriptor(object message)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            int fieldNumber = (int) caseDelegate(message);
 | 
	
		
			
				|  |  | +            int fieldNumber = caseDelegate(message);
 | 
	
		
			
				|  |  |              if (fieldNumber > 0)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                return descriptor.FindFieldByNumber(fieldNumber);
 | 
	
		
			
				|  |  | +                return descriptor.ContainingType.FindFieldByNumber(fieldNumber);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              return null;
 | 
	
		
			
				|  |  | -        }*/
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |