static void CheckAnyAuxFlow(SerializerFeatures features, ISerializer <T> serializer) { if ((features & TypeModel.FromAux) != 0 && serializer.Features.GetCategory() == SerializerFeatures.CategoryMessageWrappedAtRoot) { ThrowHelper.ThrowNotImplementedException($"Tell Marc: ambiguous category in an any/aux flow for {typeof(T).NormalizeName()}"); } }
protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value) { var serializer = TypeModel.TryGetSerializer <T>(model); if (serializer == null) { return(false); } // note this null-check is non-trivial; for value-type T it promotes the null to a default T typed = TypeHelper <T> .FromObject(value); CheckAnyAuxFlow(features, serializer); if ((features & SerializerFeatures.CategoryMessageWrappedAtRoot) == SerializerFeatures.CategoryMessageWrappedAtRoot) { if (fieldNumber != TypeModel.ListItemTag) { ThrowHelper.ThrowInvalidOperationException($"Special root-like wrapping is limited to field {TypeModel.ListItemTag}"); } state.WriteAsRoot <T>(typed, serializer); } else { state.WriteAny <T>(fieldNumber, features, typed, serializer); } return(true); }
internal KeyValuePairSerializer( ISerializer <TKey> keySerializer, SerializerFeatures keyFeatures, ISerializer <TValue> valueSerializer, SerializerFeatures valueFeatures) { _keySerializer = keySerializer; _valueSerializer = valueSerializer; _keyFeatures = keyFeatures; _valueFeatures = valueFeatures; }
public SurrogateSerializer(Type declaredType, MethodInfo toTail, MethodInfo fromTail, IRuntimeProtoSerializerNode rootTail, SerializerFeatures features) { Debug.Assert(declaredType is object, "declaredType"); Debug.Assert(rootTail is object, "rootTail"); Debug.Assert(declaredType == rootTail.ExpectedType || Helpers.IsSubclassOf(declaredType, rootTail.ExpectedType), "surrogate type mismatch"); this.declaredType = declaredType; this.rootTail = rootTail; this.toTail = toTail ?? GetConversion(true); this.fromTail = fromTail ?? GetConversion(false); this.features = features; }
public static IRuntimeProtoSerializerNode Create(RepeatedSerializerStub provider, Type keyType, Type valueType, int fieldNumber, SerializerFeatures features, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures) { if (provider == null) { ThrowHelper.ThrowArgumentNullException(nameof(provider)); } _ = provider.Serializer; // primes and validates return((IRuntimeProtoSerializerNode)Activator.CreateInstance( typeof(MapDecorator <, ,>).MakeGenericType(provider.ForType, keyType, valueType), new object[] { fieldNumber, features, keyFeatures, valueFeatures, provider })); }
internal static bool TrySerializeAny(int fieldNumber, SerializerFeatures features, Type type, TypeModel model, ref ProtoWriter.State state, object value) { do { if (Get(type).TrySerializeAny(fieldNumber, features, model, ref state, value)) { return(true); } // since we might be ignoring sub-types, we need to walk upwards and check all type = type.BaseType; } while (type is object && type != typeof(object)); return(false); }
internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer <T> serializer) { var iter = values.GetEnumerator(); try { Write(ref state, fieldNumber, category, wireType, ref iter, serializer); } finally { iter?.Dispose(); } }
/* * 22 = field 4, type String * 07 = length 7 * 08 = field 1, type Varint * 01 = -1 (zigzag) * 12 = field 2, type String * 03 = length 3 * 61-62-63 = abc * 22 = field 4, type String * 05 = length 5 * 12 = field 2, type String * 03 = length 3 * 64-65-66 = def * 22 = field 4, type String * 07 = length 7 * 08 = field 1, type Varint * 02 = 1 (zigzag) * 12 = field 2, type String * 03 = length 3 * 67-68-69 = ghi */ public void ReadWriteMapWorks(SerializerFeatures keyFeatures, string expected) { using var ms = new MemoryStream(); var data = new Dictionary <int, string> { { -1, "abc" }, { 0, "def" }, { 1, "ghi" }, }; var writer = ProtoWriter.State.Create(ms, null); try { MapSerializer.CreateDictionary <int, string>().WriteMap(ref writer, 4, default, data, keyFeatures, default);
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, SerializerFeatures features, CompatibilityLevel compatibilityLevel) { this.ctor = ctor ?? throw new ArgumentNullException(nameof(ctor)); this.members = members ?? throw new ArgumentNullException(nameof(members)); this.tails = new IRuntimeProtoSerializerNode[members.Length]; Features = features; ParameterInfo[] parameters = ctor.GetParameters(); for (int i = 0; i < members.Length; i++) { Type finalType = parameters[i].ParameterType; var repeated = model.TryGetRepeatedProvider(finalType); Type tmp = repeated?.ItemType ?? finalType; bool asReference = false; int typeIndex = model.FindOrAddAuto(tmp, false, true, false, compatibilityLevel); if (typeIndex >= 0) { asReference = model[tmp].AsReferenceDefault; } IRuntimeProtoSerializerNode tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, compatibilityLevel, tmp, out WireType wireType, asReference, false, false, true), serializer; if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); } if (repeated == null) { serializer = new TagDecorator(i + 1, wireType, false, tail); } else if (repeated.IsMap) { serializer = ValueMember.CreateMap(repeated, model, DataFormat.Default, compatibilityLevel, DataFormat.Default, DataFormat.Default, asReference, false, true, false, i + 1); } else { SerializerFeatures listFeatures = wireType.AsFeatures() | SerializerFeatures.OptionPackedDisabled; serializer = RepeatedDecorator.Create(repeated, i + 1, listFeatures, compatibilityLevel, DataFormat.Default); } tails[i] = serializer; } }
protected override bool CanSerialize(TypeModel model, out SerializerFeatures features) { ISerializer <T> ser; try { ser = TypeModel.TryGetSerializer <T>(model); } catch // then definitely no! { features = default; return(false); } if (ser == null) { features = default; return(false); } features = ser.Features; return(true); }
internal static bool CanSerialize(Type type, TypeModel model, out SerializerFeatures features) => Get(type).CanSerialize(model, out features);
public static SerializerFeatures GetCategory(this SerializerFeatures features) => features & CategoryMask;
abstract internal void Init(int[] fieldNumbers, IRuntimeProtoSerializerNode[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, bool assertKnownType, CallbackSet callbacks, Type constructType, MethodInfo factory, SerializerFeatures features);
public static IProtoTypeSerializer Create(Type forType, int[] fieldNumbers, IRuntimeProtoSerializerNode[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, bool assertKnownType, CallbackSet callbacks, Type constructType, MethodInfo factory, Type rootType, SerializerFeatures features) { var obj = (TypeSerializer)(rootType != null ? Activator.CreateInstance(typeof(InheritanceTypeSerializer <,>).MakeGenericType(rootType, forType), nonPublic: true) : Activator.CreateInstance(typeof(TypeSerializer <>).MakeGenericType(forType), nonPublic: true)); obj.Init(fieldNumbers, serializers, baseCtorCallbacks, isRootType, useConstructor, assertKnownType, callbacks, constructType, factory, features); return((IProtoTypeSerializer)obj); }
internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableArray <T> values, ISerializer <T> serializer) { var iter = new Enumerator(values); Write(ref state, fieldNumber, category, wireType, ref iter, serializer); }
public static IRuntimeProtoSerializerNode Create(RepeatedSerializerStub stub, int fieldNumber, SerializerFeatures features) { if (stub == null) { ThrowHelper.ThrowArgumentNullException(nameof(stub), $"No suitable repeated serializer resolved for {stub.ForType.NormalizeName()}"); } _ = stub.Serializer; // primes and validates return((IRuntimeProtoSerializerNode)Activator.CreateInstance(typeof(RepeatedDecorator <,>).MakeGenericType(stub.ForType, stub.ItemType), new object[] { fieldNumber, features, stub })); }
internal static bool TrySerializeAny(int fieldNumber, SerializerFeatures features, Type type, TypeModel model, ref ProtoWriter.State state, object value) => Get(type).TrySerializeAny(fieldNumber, features, model, ref state, value);
// check a few things that should be true for valid serializers internal static ISerializer <T> Verify <T>(ISerializer <T> serializer) { if (serializer == null) { return(null); } try { var features = serializer.Features; if (serializer is IRepeatedSerializer <T> ) { const SerializerFeatures PermittedRepeatedFeatures = SerializerFeatures.CategoryRepeated; if ((features & ~PermittedRepeatedFeatures) != 0) { ThrowInvalidSerializer(serializer, $"repeated serializers may only specify {PermittedRepeatedFeatures}"); } return(serializer); } var wireType = features.GetWireType(); // this also asserts that a wire-type is set switch (wireType) { case WireType.Varint: case WireType.Fixed32: case WireType.Fixed64: case WireType.SignedVarint: case WireType.String: case WireType.StartGroup: break; default: ThrowInvalidSerializer(serializer, $"invalid wire-type {wireType}"); break; } switch (features.GetCategory()) { case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: if (TypeHelper <T> .CanBePacked) { ThrowInvalidSerializer(serializer, "message serializer specified for a type that can be 'packed'"); } break; case SerializerFeatures.CategoryScalar: if (TypeHelper <T> .CanBePacked) { switch (wireType) { case WireType.Varint: case WireType.Fixed32: case WireType.Fixed64: case WireType.SignedVarint: break; default: ThrowInvalidSerializer(serializer, "invalid wire-type for a type that can be 'packed'"); break; } } break; default: features.ThrowInvalidCategory(); break; } // some features should only be specified by the caller const SerializerFeatures InvalidFeatures = SerializerFeatures.OptionClearCollection | SerializerFeatures.OptionPackedDisabled; if ((features & InvalidFeatures) != 0) { ThrowInvalidSerializer(serializer, $"serializers should not specify {InvalidFeatures}"); } return(serializer); } catch (InvalidOperationException ex) when(!ex.Data.Contains("serializer")) { ThrowInvalidSerializer(serializer, ex.Message, ex); throw; } }
protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value) => false;
protected override bool CanSerialize(TypeModel model, out SerializerFeatures features) { features = default; return(false); }