internal static OneofAccessor ForRegularOneof( OneofDescriptor descriptor, PropertyInfo caseProperty, MethodInfo clearMethod) => new OneofAccessor( descriptor, ReflectionUtil.CreateFuncIMessageInt32(caseProperty.GetGetMethod()), ReflectionUtil.CreateActionIMessage(clearMethod));
internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor) { if (!OneofAccessor.smethod_0(caseProperty)) { throw OneofAccessor.smethod_1(Module.smethod_33 <string>(966859498u)); } this.descriptor = descriptor; this.caseDelegate = ReflectionUtil.CreateFuncIMessageT <int>(caseProperty.GetGetMethod()); this.descriptor = descriptor; this.clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); }
public OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor) { if (!caseProperty.CanRead) { throw new ArgumentException("Cannot read from property"); } this.descriptor = descriptor; caseDelegate = ReflectionUtil.CreateFuncIMessageT <int>(caseProperty.GetGetMethod()); this.descriptor = descriptor; clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); }
internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor) { if (!property.CanWrite) { throw new ArgumentException("Not all required properties/methods available"); } setValueDelegate = ReflectionUtil.CreateActionIMessageObject(property.GetSetMethod()); if (descriptor.File.Syntax == Syntax.Proto3 && !descriptor.Proto.Proto3Optional) { hasDelegate = message => { throw new InvalidOperationException("HasValue is not implemented for non-optional proto3 fields"); }; var clrType = property.PropertyType; // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.) object defaultValue = descriptor.FieldType == FieldType.Message ? null : clrType == typeof(string) ? "" : clrType == typeof(ByteString) ? ByteString.Empty : Activator.CreateInstance(clrType); clearDelegate = message => SetValue(message, defaultValue); } else { // For message fields, just compare with null and set to null. // For primitive fields, use the Has/Clear methods. if (descriptor.FieldType == FieldType.Message) { hasDelegate = message => GetValue(message) != null; clearDelegate = message => SetValue(message, null); } else { MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod; if (hasMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod); MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes); if (clearMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); } } }
internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor) { if (!property.CanWrite) { throw new ArgumentException("Not all required properties/methods available"); } setValueDelegate = ReflectionUtil.CreateActionIMessageObject(property.GetSetMethod()); if (descriptor.File.Proto.Syntax == "proto2") { var pro = property.DeclaringType.GetRuntimeProperty("Has" + property.Name); MethodInfo hasMethod; #if NET35 || NET40 hasMethod = pro.GetGetMethod(); #else hasMethod = pro.GetMethod; #endif if (hasMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod); MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes); if (clearMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); } else { hasDelegate = message => { throw new InvalidOperationException("HasValue is not implemented for proto3 fields"); }; var clrType = property.PropertyType; // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.) object defaultValue = descriptor.FieldType == FieldType.Message ? null : clrType == typeof(string) ? "" : clrType == typeof(ByteString) ? ByteString.Empty : Activator.CreateInstance(clrType); clearDelegate = message => SetValue(message, defaultValue); } }
internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) : base(property, descriptor) { if (!property.CanWrite) { throw new ArgumentException("Not all required properties/methods available"); } setValueDelegate = ReflectionUtil.CreateActionIMessageObject(property.GetSetMethod()); // Note: this looks worrying in that we access the containing oneof, which isn't valid until cross-linking // is complete... but field accessors aren't created until after cross-linking. // The oneof itself won't be cross-linked yet, but that's okay: the oneof accessor is created // earlier. // Message fields always support presence, via null checks. if (descriptor.FieldType == FieldType.Message) { hasDelegate = message => GetValue(message) != null; clearDelegate = message => SetValue(message, null); } // Oneof fields always support presence, via case checks. // Note that clearing the field is a no-op unless that specific field is the current "case". else if (descriptor.RealContainingOneof != null) { var oneofAccessor = descriptor.RealContainingOneof.Accessor; hasDelegate = message => oneofAccessor.GetCaseFieldDescriptor(message) == descriptor; clearDelegate = message => { // Clear on a field only affects the oneof itself if the current case is the field we're accessing. if (oneofAccessor.GetCaseFieldDescriptor(message) == descriptor) { oneofAccessor.Clear(message); } }; } // Primitive fields always support presence in proto2, and support presence in proto3 for optional fields. else if (descriptor.File.Syntax == Syntax.Proto2 || descriptor.Proto.Proto3Optional) { MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod; if (hasMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod); MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes); if (clearMethod == null) { throw new ArgumentException("Not all required properties/methods are available"); } clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); } // What's left? // Primitive proto3 fields without the optional keyword, which aren't in oneofs. else { hasDelegate = message => { throw new InvalidOperationException("Presence is not implemented for this field"); }; // While presence isn't supported, clearing still is; it's just setting to a default value. var clrType = property.PropertyType; if (clrType is ILRuntimeWrapperType wrapperType) { clrType = wrapperType.RealType; } object defaultValue = clrType == typeof(string) ? "" : clrType == typeof(ByteString) ? ByteString.Empty : (clrType is ILRuntimeType) ? (clrType as ILRuntimeType).ILType.Instantiate() : Activator.CreateInstance(clrType); clearDelegate = message => SetValue(message, defaultValue); } }