private IProtoSerializer BuildSerializer() { WireType wireType; IProtoSerializer ser = GetCoreSerializer(itemType ?? memberType, out wireType); // apply tags ser = new TagDecorator(fieldNumber, wireType, isStrict, ser); // apply lists if appropriate if (itemType != null) { Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail"); if (memberType.IsArray) { ser = new ArrayDecorator(ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None); } else { ser = new ListDecorator(memberType, defaultType, ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None); } } else if (defaultValue != null && !isRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } return(ser); }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true); if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); } // apply tags if (itemType != null && SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(model, ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } // apply lists if appropriate if (itemType != null) { #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType; #endif Helpers.DebugAssert(underlyingItemType == ser.ExpectedType || (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType)) , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); if (memberType.IsArray) { ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull); } else { ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull); } } else if (defaultValue != null && !IsRequired && getSpecified == null) { // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue, // as does "IsRequired" ser = new DefaultValueDecorator(model, defaultValue, ser); } if (memberType == model.MapType(typeof(Uri))) { ser = new UriDecorator(model, ser); } #if PORTABLE else if (memberType.FullName == typeof(Uri).FullName) { // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri) ser = new ReflectedUriDecorator(memberType, model, ser); } #endif if (member != null) { PropertyInfo prop = member as PropertyInfo; if (prop != null) { ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser); } else { FieldInfo fld = member as FieldInfo; if (fld != null) { ser = new FieldDecorator(parentType, (FieldInfo)member, ser); } else { throw new InvalidOperationException(); } } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return(ser); } finally { model.ReleaseLock(opaqueToken); } }
IProtoSerializerWithWireType BuildValueFinalSerializer(ValueSerializationSettings settings, bool isMemberOrNested, out WireType wireType, int levelNumber) { object defaultValue; var l = CompleteLevel(settings, levelNumber, out defaultValue).Basic; // to ensure that model can be copied and used again for (int i = 1; i <= 3; i++) { var l2 = CompleteLevel(settings, levelNumber, out defaultValue); Debug.Assert(l.Equals(l2.Basic)); } Debug.Assert(l.ContentBinaryFormatHint != null, "l.ContentBinaryFormatHint != null"); Debug.Assert(l.WriteAsDynamicType != null, "l.WriteAsDynamicType != null"); Debug.Assert(l.Collection.Append != null, "l.Collection.Append != null"); // postpone all checks for types when adding member till BuildSerializer, resolve everything only on buildserializer! till that have only local not inherited settings. // do not allow EnumPassthru and other settings to affect anything until buildling serializer wireType = 0; Type itemType = l.Collection.ItemType ?? l.EffectiveType; bool itemTypeCanBeNull = CanTypeBeNull(itemType); bool isPacked = CanBePackedCollection(l); IProtoSerializerWithWireType ser = null; if (l.Collection.IsCollection) { Type nestedItemType = null; Type nestedDefaultType = null; int idx = _model.FindOrAddAuto(itemType, false, true, false); MetaType type = idx < 0 ? null : _model[itemType]; if (!type?.GetFinalSettingsCopy().IgnoreListHandling ?? true) { MetaType.ResolveListTypes(_model, itemType, ref nestedItemType, ref nestedDefaultType); } bool itemIsNestedCollection = nestedItemType != null; // primitive types except System.Object may be handled as nested through recursion bool tryHandleAsRegistered = !isMemberOrNested || itemType == _model.MapType(typeof(object)); if (tryHandleAsRegistered) { var nestedLevel = settings.GetSettingsCopy(levelNumber + 1); nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType); settings.SetSettings(nestedLevel, levelNumber + 1); // should use its level settings and merge from type, ... ser = BuildValueFinalSerializer(settings, true, out wireType, levelNumber + 1); //object dummy = null; //ser = TryGetCoreSerializer(l.ContentBinaryFormatHint.Value, nestedLevel.Basic.EffectiveType, out wireType, ref nestedLevel.Basic.Format, nestedLevel.Basic.WriteAsDynamicType.GetValueOrDefault(), l.Collection.Append.Value, isPacked, true, ref dummy); //if (ser != null) // ThrowIfHasMoreLevels(settings, levelNumber + 1, l, ", no more nested type detected"); } else if (!itemIsNestedCollection) { var nestedLevel = settings.GetSettingsCopy(levelNumber + 1); nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType); nestedLevel.Basic.Collection.ItemType = null; // IgnoreListHandling or not a collection settings.SetSettings(nestedLevel, levelNumber + 1); ser = BuildValueFinalSerializer(settings, true, out wireType, levelNumber + 1); } if (ser == null && itemIsNestedCollection) { // if we already tried to lookup registered type no need to do it again MetaType metaType; if (_model.FindOrAddAuto(itemType, false, true, false, out metaType) >= 0) { nestedDefaultType = metaType.GetFinalSettingsCopy().ConstructType ?? nestedDefaultType ?? metaType.Type; } var nestedLevel = settings.GetSettingsCopy(levelNumber + 1); if (nestedLevel.Basic.Collection.ConcreteType == null) { nestedLevel.Basic.Collection.ConcreteType = nestedDefaultType; } if (nestedLevel.IsNotAssignable) { throw new ProtoException("Nested collection item should be assignable"); } nestedLevel.Basic.Collection.Append = false; // TODO throw if set to true: throw new ProtoException("AppendCollection is not supported for nested types: " + objectType.Name); if (nestedLevel.Basic.Collection.ItemType == null) { nestedLevel.Basic.Collection.ItemType = nestedItemType; } else if (!Helpers.IsAssignableFrom(nestedItemType, nestedLevel.Basic.Collection.ItemType)) { throw new ProtoException( "Nested collection item type " + nestedLevel.Basic.Collection.ItemType + " is not assignable to " + nestedItemType + " for declared collection type " + l.EffectiveType); } nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType); settings.SetSettings(nestedLevel, levelNumber + 1); WireType wt; ser = BuildValueFinalSerializer( settings, true, out wt, levelNumber + 1); isPacked = false; } } else { // handled outside and not wrapped with collection if (!isMemberOrNested) { l.Format = ValueFormat.Compact; } isPacked = false; // it's not even a collection ser = TryGetCoreSerializer(l.ContentBinaryFormatHint.Value, itemType, out wireType, ref l.Format, l.WriteAsDynamicType.Value, l.Collection.Append.Value, isPacked, true, ref defaultValue); if (ser != null) { ThrowIfHasMoreLevels(settings, levelNumber, l, ", no more nested type detected"); } } if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + itemType.FullName); } if (itemTypeCanBeNull && ( (Helpers.GetNullableUnderlyingType(itemType) != null && Helpers.GetNullableUnderlyingType(ser.ExpectedType) == null) // TODO get rid of ugly casting, maybe use builder pattern || (!Helpers.IsValueType(itemType) && !(ser is NetObjectValueDecorator)) )) { // nested level may be not collection and already wrapped with nonull, may later add check whether handled as registered vs as nested if (!(ser is NoNullDecorator)) { // if not wrapped with net obj - wrap with write-null check ser = new NoNullDecorator(_model, ser, l.Collection.ItemType != null); // throw only for collection elements, otherwise don't write } } if (itemType != ser.ExpectedType && (!l.WriteAsDynamicType.Value || !Helpers.IsAssignableFrom(ser.ExpectedType, itemType))) { throw new ProtoException(string.Format("Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, itemType)); } // apply lists if appropriate if (l.Collection.IsCollection) { bool protoCompatibility = l.Collection.Format == CollectionFormat.Protobuf || l.Collection.Format == CollectionFormat.ProtobufNotPacked; WireType packedReadWt; if (!protoCompatibility) { packedReadWt = WireType.None; Debug.Assert(!isPacked); // should be determinated before passing to TryGetCoreSerializer isPacked = false; } else { packedReadWt = CanPack(l.Collection.ItemType, l.ContentBinaryFormatHint) ? l.Collection.PackedWireTypeForRead.GetValueOrDefault(wireType) : WireType.None; } if (l.EffectiveType.IsArray) { if (l.EffectiveType.GetArrayRank() == 1) { ser = new ArrayDecorator( _model, ser, isPacked, packedReadWt, l.EffectiveType, !l.Collection.Append.Value, l.Collection.ArrayLengthReadLimit.Value, protoCompatibility); } else { if (protoCompatibility) { throw new NotSupportedException("Multi-dimensional arrays are supported only in Enhanced collection format"); } ser = new MultiDimensionalArrayDecorator( _model, ser, l.EffectiveType, !l.Collection.Append.Value, l.Collection.ArrayLengthReadLimit.Value); } } else { ser = ListDecorator.Create( _model, l.EffectiveType, l.Collection.ConcreteType, ser, isPacked, packedReadWt, !l.Collection.Append.Value, protoCompatibility, true); } if (isMemberOrNested) { if (MetaType.IsNetObjectValueDecoratorNecessary(_model, l.Format)) { ser = new NetObjectValueDecorator( ser, Helpers.GetNullableUnderlyingType(l.EffectiveType) != null, l.Format == ValueFormat.Reference || l.Format == ValueFormat.LateReference, l.Format == ValueFormat.LateReference && CanTypeBeAsLateReferenceOnBuildStage(_model.GetKey(l.EffectiveType, false, true), _model), !_model.ProtoCompatibility.SuppressNullWireType, _model); } else if (!Helpers.IsValueType(l.EffectiveType) || Helpers.GetNullableUnderlyingType(l.EffectiveType) != null) { ser = new NoNullDecorator(_model, ser, false); } } if (l.EffectiveType != ser.ExpectedType && (!l.WriteAsDynamicType.Value || !Helpers.IsAssignableFrom(ser.ExpectedType, itemType))) { throw new ProtoException(string.Format("Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, itemType)); } } if (levelNumber == 0 && defaultValue != null) { ser = new DefaultValueDecorator(_model, defaultValue, ser); } return(ser); }
private IProtoSerializer BuildSerializer() { bool lockTaken = false; try { model.TakeLock(ref lockTaken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType); if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); } // apply tags ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); // apply lists if appropriate if (itemType != null) { Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail"); if (memberType.IsArray) { ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList); } else { ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList); } } else if (defaultValue != null && !IsRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } if (member != null) { switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return(ser); } finally { model.ReleaseLock(lockTaken); } }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken);// check nobody is still adding this type var member = backingMember ?? originalMember; IProtoSerializer ser; if (IsMap) { ResolveMapTypes(out var dictionaryType, out var keyType, out var valueType); if (dictionaryType == null) { throw new InvalidOperationException("Unable to resolve map type for type: " + memberType.FullName); } var concreteType = defaultType; if (concreteType == null && Helpers.IsClass(memberType)) { concreteType = memberType; } var keySer = TryGetCoreSerializer(model, MapKeyFormat, keyType, out var keyWireType, false, false, false, false); if (!AsReference) { AsReference = MetaType.GetAsReferenceDefault(model, valueType); } var valueSer = TryGetCoreSerializer(model, MapValueFormat, valueType, out var valueWireType, AsReference, DynamicType, false, true); #if PROFILE259 IEnumerable <ConstructorInfo> ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetTypeInfo().DeclaredConstructors; if (ctors.Count() != 1) { throw new InvalidOperationException("Unable to resolve MapDecorator constructor"); } ser = (IProtoSerializer)ctors.First().Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber, DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList }); #else var ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetConstructors( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (ctors.Length != 1) { throw new InvalidOperationException("Unable to resolve MapDecorator constructor"); } ser = (IProtoSerializer)ctors[0].Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber, DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList }); #endif } else { WireType wireType; Type finalType = itemType == null ? memberType : itemType; ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, AsReference, DynamicType, OverwriteList, true); if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); } // apply tags if (itemType != null && SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(model, ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } // apply lists if appropriate if (itemType != null) { Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType; Helpers.DebugAssert(underlyingItemType == ser.ExpectedType || (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType)) , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); if (memberType.IsArray) { ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull); } else { ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull); } } else if (defaultValue != null && !IsRequired && getSpecified == null) { // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue, // as does "IsRequired" ser = new DefaultValueDecorator(model, defaultValue, ser); } if (memberType == model.MapType(typeof(Uri))) { ser = new UriDecorator(model, ser); } #if PORTABLE else if (memberType.FullName == typeof(Uri).FullName) { // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri) ser = new ReflectedUriDecorator(memberType, model, ser); } #endif } if (member != null) { if (member is PropertyInfo prop) { ser = new PropertyDecorator(model, parentType, prop, ser); } else if (member is FieldInfo fld) { ser = new FieldDecorator(parentType, fld, ser); } else { throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return(ser); } finally { model.ReleaseLock(opaqueToken); } }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList); if (ser == null) { throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); } // apply tags if (itemType != null && SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } // apply lists if appropriate if (itemType != null) { #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = SupportNull ? itemType : Nullable.GetUnderlyingType(itemType) ?? itemType; #endif Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); if (memberType.IsArray) { ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull); } else { ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList, SupportNull); } } else if (defaultValue != null && !IsRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } if (member != null) { switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return(ser); } finally { model.ReleaseLock(opaqueToken); } }
private IProtoSerializer BuildSerializer() { IProtoSerializer serializer2; int opaqueToken = 0; try { WireType type; this.model.TakeLock(ref opaqueToken); Type type2 = (this.itemType == null) ? this.memberType : this.itemType; IProtoSerializer tail = TryGetCoreSerializer(this.model, this.dataFormat, type2, out type, this.asReference, this.dynamicType, this.OverwriteList, true); if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + type2.FullName); } if ((this.itemType != null) && this.SupportNull) { if (this.IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } tail = new TagDecorator(1, type, this.IsStrict, tail); tail = new NullDecorator(this.model, tail); tail = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, tail); } else { tail = new TagDecorator(this.fieldNumber, type, this.IsStrict, tail); } if (this.itemType != null) { if (!this.SupportNull) { Helpers.GetUnderlyingType(this.itemType); } if (this.memberType.IsArray) { tail = new ArrayDecorator(this.model, tail, this.fieldNumber, this.IsPacked, type, this.memberType, this.OverwriteList, this.SupportNull); } else { tail = new ListDecorator(this.model, this.memberType, this.defaultType, tail, this.fieldNumber, this.IsPacked, type, (this.member != null) && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull); } } else if (((this.defaultValue != null) && !this.IsRequired) && (this.getSpecified == null)) { tail = new DefaultValueDecorator(this.model, this.defaultValue, tail); } if (this.memberType == this.model.MapType(typeof(Uri))) { tail = new UriDecorator(this.model, tail); } if (this.member != null) { PropertyInfo member = this.member as PropertyInfo; if (member != null) { tail = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, tail); } else { FieldInfo info2 = this.member as FieldInfo; if (info2 == null) { throw new InvalidOperationException(); } tail = new FieldDecorator(this.parentType, (FieldInfo)this.member, tail); } if ((this.getSpecified != null) || (this.setSpecified != null)) { tail = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, tail); } } serializer2 = tail; } finally { this.model.ReleaseLock(opaqueToken); } return(serializer2); }
// Token: 0x0600040A RID: 1034 RVA: 0x00015168 File Offset: 0x00013368 private IProtoSerializer BuildSerializer() { int opaqueToken = 0; IProtoSerializer result; try { this.model.TakeLock(ref opaqueToken); Type type = (this.itemType == null) ? this.memberType : this.itemType; WireType wireType; IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(this.model, this.dataFormat, type, out wireType, this.asReference, this.dynamicType, this.OverwriteList, true); if (protoSerializer == null) { throw new InvalidOperationException("No serializer defined for type: " + type.FullName); } if (this.itemType != null && this.SupportNull) { if (this.IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } protoSerializer = new TagDecorator(1, wireType, this.IsStrict, protoSerializer); protoSerializer = new NullDecorator(this.model, protoSerializer); protoSerializer = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, protoSerializer); } else { protoSerializer = new TagDecorator(this.fieldNumber, wireType, this.IsStrict, protoSerializer); } if (this.itemType != null) { if (!this.SupportNull) { if (Helpers.GetUnderlyingType(this.itemType) == null) { Type type2 = this.itemType; } } else { Type type3 = this.itemType; } if (this.memberType.IsArray) { protoSerializer = new ArrayDecorator(this.model, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.memberType, this.OverwriteList, this.SupportNull); } else { protoSerializer = ListDecorator.Create(this.model, this.memberType, this.defaultType, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.member != null && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull); } } else if (this.defaultValue != null && !this.IsRequired && this.getSpecified == null) { protoSerializer = new DefaultValueDecorator(this.model, this.defaultValue, protoSerializer); } if (this.memberType == this.model.MapType(typeof(Uri))) { protoSerializer = new UriDecorator(this.model, protoSerializer); } if (this.member != null) { if (this.member is PropertyInfo) { protoSerializer = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, protoSerializer); } else { if (!(this.member is FieldInfo)) { throw new InvalidOperationException(); } protoSerializer = new FieldDecorator(this.parentType, (FieldInfo)this.member, protoSerializer); } if (this.getSpecified != null || this.setSpecified != null) { protoSerializer = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, protoSerializer); } } result = protoSerializer; } finally { this.model.ReleaseLock(opaqueToken); } return(result); }