Пример #1
0
        /// <summary>
        /// Returns true if the given RuntimeTypeModel contains a definition for the given type.
        /// </summary>
        private static bool ContainsType(RuntimeTypeModel model, Type type)
        {
            bool emit      = !type.IsNullableType();
            bool fastCheck = model.IsDefined(type);

            // DEBUGGING: comment this if statement out if there are protobuf-net related issues
            if (emit)
            {
                return(fastCheck);
            }

            foreach (MetaType metaType in model.GetTypes())
            {
                if (metaType.Type == type)
                {
                    if (emit && fastCheck != true)
                    {
                        UnityEngine.Debug.Log("Fast check failed for " + type.CSharpName() + " (nullabe? " + type.IsNullableType() + ")!");
                    }
                    return(true);
                }
            }

            if (emit && fastCheck != false)
            {
                UnityEngine.Debug.Log("Fast check failed for " + type.CSharpName() + " (nullabe? " + type.IsNullableType() + ")!");
            }
            return(false);
        }
        public override bool CanBeResolvedUsing(RuntimeTypeModel protobufModel)
        {
            var types    = protobufModel.GetTypes().Cast <MetaType>();
            var baseType =
                types.SingleOrDefault(t => t.Type == typeof(T).BaseType);

            return(baseType != null);
        }
 private static bool AlreadyContainsType(Type type, RuntimeTypeModel model)
 {
     foreach (var t in model.GetTypes())
     {
         var knownType = ((MetaType)t).Type;
         if (knownType == type)
         {
             return(true);
         }
     }
     return(false);
 }
Пример #4
0
        static string GetSchema(RuntimeTypeModel runtimeTypeModel, CliArgs args)
        {
            BasicList requiredTypes = new BasicList();

            foreach (MetaType meta in runtimeTypeModel.GetTypes())
            {
                MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false);
                if (!requiredTypes.Contains(tmp))
                {
                    requiredTypes.Add(tmp);
                }
            }

            StringBuilder headerBuilder = new StringBuilder();

            headerBuilder.Append("syntax = \"proto2\";").AppendLine();
            headerBuilder.AppendLine();

            headerBuilder.Append("option java_package = \"").Append(args.JavaPackage).Append("\";").AppendLine();
            headerBuilder.Append("option java_multiple_files = true;").AppendLine();

            bool          requiresBclImport = false;
            StringBuilder bodyBuilder       = new StringBuilder();

            // sort them by schema-name
            MetaType[] metaTypesArr = new MetaType[requiredTypes.Count];
            requiredTypes.CopyTo(metaTypesArr, 0);
            Array.Sort(metaTypesArr, MetaType.Comparer.Default);

            // write the messages
            for (int i = 0; i < metaTypesArr.Length; i++)
            {
                MetaType tmp = metaTypesArr[i];
                if (tmp.IsList)
                {
                    continue;
                }
                tmp.WriteSchema(bodyBuilder, 0, ref requiresBclImport);
                bodyBuilder.AppendLine();
            }

            if (requiresBclImport)
            {
                headerBuilder.AppendLine();
                headerBuilder.Append("import \"dotnettype.proto\";").AppendLine();
            }

            return(headerBuilder.Append(bodyBuilder).ToString());
        }
        private void Initialize()
        {
            if (_Model.GetTypes() != null)
            {
                return;
            }

            _Model.Add(_primaryType, true);
            foreach (var knownType in _secondaryTypes)
            {
                _Model.Add(knownType, true);
            }

            _Model.CompileInPlace();
        }
Пример #6
0
        public static RuntimeTypeModel CreateTypeModel(IEnumerable <Type> types)
        {
            RuntimeTypeModel typeModel = TypeModel.Create();

            foreach (var t in types)
            {
                var contract = t.GetCustomAttributes(typeof(ProtoContractAttribute), false);
                if (contract.Length > 0)
                {
                    MetaType metaType = typeModel.Add(t, true);

                    // support ISerializationCallbackReceiver
                    if (typeof(ISerializationCallbackReceiver).IsAssignableFrom(t))
                    {
                        MethodInfo beforeSerializeMethod  = t.GetMethod("OnBeforeSerialize");
                        MethodInfo afterDeserializeMethod = t.GetMethod("OnAfterDeserialize");

                        metaType.SetCallbacks(beforeSerializeMethod, null, null, afterDeserializeMethod);
                    }
                }
            }

            UniBufConfig   config  = UniBufHelper.GetConfig();
            HashSet <Type> hashSet = new HashSet <Type>();

            foreach (MetaType metaType in typeModel.GetTypes().Cast <MetaType>().ToArray())
            {
                hashSet.Add(metaType.Type);
                OverrideMetaType(metaType, config.TypeOverride);
                foreach (ValueMember valueMember in metaType.GetFields())
                {
                    if (valueMember.MemberType.IsPrimitive || valueMember.MemberType == typeof(string))
                    {
                        continue;
                    }
                    if (!hashSet.Contains(valueMember.MemberType))
                    {
                        MetaType memberType = typeModel.Add(valueMember.MemberType, false);
                        hashSet.Add(memberType.Type);
                        OverrideMetaType(memberType, config.TypeOverride);
                    }
                }
            }

            return(typeModel);
        }
Пример #7
0
        // Token: 0x06000AFD RID: 2813 RVA: 0x000225A8 File Offset: 0x000207A8
        public static void PopulateTypes(Type t)
        {
            using (IEnumerator enumerator = RuntimeTypeModel.Default.GetTypes().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    MetaType metaType;
                    if ((metaType = (enumerator.Current as MetaType)) != null && metaType.Type == t)
                    {
                        return;
                    }
                }
            }
            Type        typeFromHandle = typeof(object);
            List <Type> list           = new List <Type>();

            do
            {
                list.Insert(0, t);
                t = t.BaseType;
            }while (t != null && t != typeFromHandle);
            for (int i = 0; i < list.Count - 1; i++)
            {
                Type             type      = list[i];
                MetaType         metaType2 = null;
                bool             flag      = false;
                RuntimeTypeModel @default  = RuntimeTypeModel.Default;
                foreach (object obj in ((@default != null) ? @default.GetTypes() : null))
                {
                    MetaType metaType3 = (MetaType)obj;
                    if (metaType3.Name.Equals(type.Name))
                    {
                        flag      = true;
                        metaType2 = metaType3;
                        break;
                    }
                }
                if (!flag)
                {
                    RuntimeTypeModel default2 = RuntimeTypeModel.Default;
                    metaType2 = ((default2 != null) ? default2.Add(type, true) : null);
                }
                metaType2.AddSubType((metaType2.GetSubtypes().Length + 1) * 100, list[i + 1]);
            }
        }
Пример #8
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="model">the runtime model to update. Existing types already added to the model will be considered as built-in</param>
 public RuntimeTypeModelUpdater(RuntimeTypeModel model)
 {
     _model      = model;
     _lock       = new object();
     _subTypes   = new Dictionary <Type, HashSet <Type> >();
     _builtTypes = new ConcurrentDictionary <Type, bool>();
     // any types that the model already defines need to be considered as built-in.
     // this is important starting from V3 of protobuf-net
     foreach (MetaType metaType in model.GetTypes())
     {
         _builtTypes.TryAdd(metaType.Type, false);
     }
     /// starting from protobuf-net V3, the following built-in types need to be added explicitly. Attempts to check them explicitly using <see cref="TypeModel.CanSerializeBasicType(Type)"/> yields unwanted side effects
     /// by silently registering the type argument.
     _builtTypes.TryAdd(typeof(DateTime), false);
     _builtTypes.TryAdd(typeof(string), false);
     _builtTypes.TryAdd(typeof(decimal), false);
     _builtTypes.TryAdd(typeof(Guid), false);
     _builtTypes.TryAdd(typeof(TimeSpan), false);
     _builtTypes.TryAdd(typeof(Uri), false);
     _builtTypes.TryAdd(typeof(byte), false);
 }
        public override RuntimeTypeModel GetRuntimeTypeModel(RuntimeTypeModel protobufModel)
        {
            if (!_fieldIdSet)
            {
                throw new SubclassFieldIdNotSetException("Field ID of subclass " + typeof(T).Name + " not set");
            }
            base.GetRuntimeTypeModel(protobufModel);

            var types    = protobufModel.GetTypes().Cast <MetaType>();
            var baseType =
                types.SingleOrDefault(t => t.Type == typeof(T).BaseType);

            if (baseType.GetSubtypes().Any(s => s.FieldNumber == _subclassFieldId))
            {
                throw new FieldIdAlreadyUsedException(_subclassFieldId,
                                                      baseType.GetSubtypes().First(s => s.FieldNumber == _subclassFieldId).DerivedType);
            }

            baseType.AddSubType(_subclassFieldId, typeof(T));

            return(protobufModel);
        }
Пример #10
0
        // Token: 0x060000F9 RID: 249 RVA: 0x00004008 File Offset: 0x00002208
        public static void PopulateTypes(Type t)
        {
            using (IEnumerator enumerator = RuntimeTypeModel.Default.GetTypes().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    MetaType metaType;
                    if ((metaType = (enumerator.Current as MetaType)) != null && metaType.Type == t)
                    {
                        return;
                    }
                }
            }
            Type        typeFromHandle = typeof(object);
            List <Type> list           = new List <Type>();

            do
            {
                list.Insert(0, t);
                t = t.BaseType;
                if (t == null)
                {
                    break;
                }
            }while (t != typeFromHandle);
            int i = 0;

            while (i < list.Count - 1)
            {
                Type             type      = list[i];
                MetaType         metaType2 = null;
                bool             flag      = false;
                RuntimeTypeModel expr_A3   = RuntimeTypeModel.Default;
                using (IEnumerator enumerator = ((expr_A3 != null) ? expr_A3.GetTypes() : null).GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        MetaType metaType3 = (MetaType)enumerator.Current;
                        if (metaType3.Name.Equals(type.Name))
                        {
                            flag      = true;
                            metaType2 = metaType3;
                            break;
                        }
                    }
                    goto IL_142;
                }
                goto IL_101;
IL_117:
                metaType2.AddSubType((metaType2.GetSubtypes().Length + 1) * 100, list[i + 1]);
                i++;
                continue;
IL_101:
                RuntimeTypeModel expr_106 = RuntimeTypeModel.Default;
                metaType2 = ((expr_106 != null) ? expr_106.Add(type, true) : null);
                goto IL_117;
IL_142:
                if (!flag)
                {
                    goto IL_101;
                }
                goto IL_117;
            }
        }
        /// <summary>
        /// Apply include mappings via assembly reflection (<see cref="ProtoBaseAttribute"/>).<br />
        /// Important: This must be called before any serialization happen.
        /// </summary>
        /// <param name="model">The RuntimeTypeModel</param>
        /// <param name="assemblyFilter">The custom assembly filter</param>
        /// <param name="implicitFields">The default import of base type fields, if nothing is specified.</param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="InvalidDataException"></exception>
        public static void ApplyProtoBase(this RuntimeTypeModel model, Func <Assembly, bool> assemblyFilter, ImplicitFields implicitFields = ImplicitFields.AllPublic)
        {
            AppDomain.CurrentDomain.GetAssemblies().Where(a => assemblyFilter?.Invoke(a) != false)
            .AsParallel().SelectMany(a =>
                                     a.GetTypes().Where(t => t.IsClass && t.GetCustomAttributes <ProtoBaseAttribute>(false).Any()))
            .ForAll(t =>
            {
                foreach (var attr in t.GetCustomAttributes <ProtoBaseAttribute>(false))
                {
                    if (attr.ConcreteType != null)
                    {
                        if (t.IsGenericType)
                        {
                            if (!attr.ConcreteType.IsGenericType ||
                                attr.ConcreteType.GetGenericTypeDefinition() != t)
                            {
                                throw new ArgumentException("Concrete type must be assignable from this type");
                            }
                        }
                        else if (!t.IsAssignableFrom(attr.ConcreteType))
                        {
                            throw new ArgumentException("Concrete type must be assignable from this type");
                        }
                    }

                    var type = attr.ConcreteType ?? t;

                    if (type.BaseType == null)
                    {
                        throw new ArgumentException("BaseType cannot be null");
                    }

                    if (type.IsGenericType && type.GenericTypeArguments.Length == 0)
                    {
                        throw new InvalidDataException($"Cannot add generic type without concrete definition. '{type.FullName}'");
                    }

                    Type baseType;
                    if (attr.InterfaceType != null)
                    {
                        if (!attr.InterfaceType.IsInterface)
                        {
                            throw new ArgumentException($"The attributed InterfaceType must be an interface. '{attr.InterfaceType.FullName}'");
                        }

                        if (!attr.InterfaceType.IsAssignableFrom(type))
                        {
                            throw new ArgumentException(
                                $"BaseType '{attr.InterfaceType.FullName}' must be assignable from type {type.FullName}.");
                        }

                        baseType = attr.InterfaceType;
                    }
                    else
                    {
                        if (type.BaseType == typeof(object))
                        {
                            baseType = type.GetInterfaces().FirstOrDefault();
                            if (baseType == null)
                            {
                                throw new ArgumentException($"BaseType cannot be of type '{typeof(object).FullName}' and no interfaces are defined.");
                            }
                        }
                        else
                        {
                            baseType = type.BaseType;
                        }
                    }

                    var metaType = model.Add(type, true);
                    if (metaType.BaseType != null && metaType.BaseType.Type != baseType)
                    {
                        throw new InvalidDataException(
                            $"Type '{type.FullName}' has already an assigned base type '{metaType.BaseType.Type.FullName}'");
                    }

                    MetaType baseMetaType;
                    if (baseType.IsClass &&
                        baseType.GetCustomAttribute <DataContractAttribute>() == null &&
                        baseType.GetCustomAttribute <ProtoContractAttribute>() == null &&
                        model.GetTypes().OfType <MetaType>().All(a => a.Type != baseType))
                    {
                        baseMetaType = model.Add(baseType, true);

                        void ApplyImplicitFields(BindingFlags bindingFlags)
                        {
                            var fields = baseType
                                         .GetProperties(bindingFlags | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                                         .Cast <MemberInfo>()
                                         .Concat(baseType.GetFields(
                                                     bindingFlags | BindingFlags.Instance | BindingFlags.DeclaredOnly)).ToList();

                            if (fields.Any(a =>
                                           a.GetCustomAttribute <DataMemberAttribute>() != null ||
                                           a.GetCustomAttribute <ProtoMemberAttribute>() != null))
                            {
                                return;
                            }

                            var fieldNumber = 1;
                            foreach (var name in fields.Where(x =>
                                                              x.GetCustomAttribute <IgnoreDataMemberAttribute>() == null &&
                                                              x.GetCustomAttribute <ProtoIgnoreAttribute>() == null &&
                                                              x.GetCustomAttribute <CompilerGeneratedAttribute>() == null)
                                     .Select(a => a.Name))
                            {
                                baseMetaType.Add(fieldNumber++, name);
                            }
                        }

                        switch (implicitFields)
                        {
                        case ImplicitFields.AllPublic:
                            ApplyImplicitFields(BindingFlags.Public);
                            break;

                        case ImplicitFields.AllFields:
                            ApplyImplicitFields(BindingFlags.Public | BindingFlags.NonPublic);
                            break;

                        case ImplicitFields.None:
                            // Do noting
                            break;
                        }
                    }
                    else
                    {
                        baseMetaType = model.Add(baseType, true);
                    }

                    var rootMetaType = baseMetaType;
                    while (rootMetaType.BaseType != null)
                    {
                        rootMetaType = rootMetaType.BaseType;
                    }

                    void ValidateMetaTypes(MetaType mt)
                    {
                        if (mt.HasSubtypes)
                        {
                            if (mt.GetSubtypes().Any(a => a.FieldNumber == attr.FieldNumber))
                            {
                                throw new InvalidDataException(
                                    $"Cannot assign field number '{attr.FieldNumber}' for '{type.FullName}' on '{baseType.FullName}'. It's already being assigned to '{mt.Type.FullName}' in the hierarchy.");
                            }

                            foreach (var en in mt.GetSubtypes())
                            {
                                ValidateMetaTypes(en.DerivedType);
                            }
                        }
                    }

                    ValidateMetaTypes(rootMetaType);
                    baseMetaType.AddSubType(attr.FieldNumber, type);
                }
            });
        }