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 static void TestEnumerableListPatterns(TypeModel model, BasicList candidates, Type iType) { if (iType.IsGenericType) { Type typeDef = iType.GetGenericTypeDefinition(); if (typeDef == model.MapType(typeof(IEnumerable <>)) || typeDef == model.MapType(typeof(ICollection <>)) || typeDef.FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") { Type[] iTypeArgs = iType.GetGenericArguments(); if (!candidates.Contains(iTypeArgs[0])) { candidates.Add(iTypeArgs[0]); } } } }
private void CascadeDependents(BasicList list, MetaType metaType) { if (metaType.IsList) { Type itemType = TypeModel.GetListItemType(this, metaType.Type); WireType defaultWireType; if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType, out defaultWireType, false, false, false, false) == null) { int index = this.FindOrAddAuto(itemType, false, false, false); if (index >= 0) { MetaType tmp = ((MetaType)this.types[index]).GetSurrogateOrBaseOrSelf(false); if (!list.Contains(tmp)) { list.Add(tmp); this.CascadeDependents(list, tmp); return; } } } } else { MetaType tmp; if (metaType.IsAutoTuple) { MemberInfo[] mapping; if (MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null) { for (int i = 0; i < mapping.Length; i++) { Type type = null; if (mapping[i] is PropertyInfo) { type = ((PropertyInfo)mapping[i]).PropertyType; } else { if (mapping[i] is FieldInfo) { type = ((FieldInfo)mapping[i]).FieldType; } } WireType defaultWireType2; if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType2, false, false, false, false) == null) { int index2 = this.FindOrAddAuto(type, false, false, false); if (index2 >= 0) { tmp = ((MetaType)this.types[index2]).GetSurrogateOrBaseOrSelf(false); if (!list.Contains(tmp)) { list.Add(tmp); this.CascadeDependents(list, tmp); } } } } } } else { foreach (ValueMember member in metaType.Fields) { Type type2 = member.ItemType; if (type2 == null) { type2 = member.MemberType; } WireType defaultWireType3; if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type2, out defaultWireType3, false, false, false, false) == null) { int index3 = this.FindOrAddAuto(type2, false, false, false); if (index3 >= 0) { tmp = ((MetaType)this.types[index3]).GetSurrogateOrBaseOrSelf(false); if (!list.Contains(tmp)) { list.Add(tmp); this.CascadeDependents(list, tmp); } } } } } if (metaType.HasSubtypes) { SubType[] subtypes = metaType.GetSubtypes(); for (int j = 0; j < subtypes.Length; j++) { SubType subType = subtypes[j]; tmp = subType.DerivedType.GetSurrogateOrSelf(); if (!list.Contains(tmp)) { list.Add(tmp); this.CascadeDependents(list, tmp); } } } tmp = metaType.BaseType; if (tmp != null) { tmp = tmp.GetSurrogateOrSelf(); } if (tmp != null && !list.Contains(tmp)) { list.Add(tmp); this.CascadeDependents(list, tmp); } } }
internal static Type GetListItemType(TypeModel model, Type listType) { if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } BasicList candidates = new BasicList(); MethodInfo[] methods = listType.GetMethods(); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (!method.IsStatic && !(method.Name != "Add")) { ParameterInfo[] parameters = method.GetParameters(); Type paramType; if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) { candidates.Add(paramType); } } } string name = listType.Name; if (name == null || (name.IndexOf("Queue") < 0 && name.IndexOf("Stack") < 0)) { TypeModel.TestEnumerableListPatterns(model, candidates, listType); Type[] interfaces = listType.GetInterfaces(); for (int j = 0; j < interfaces.Length; j++) { Type iType = interfaces[j]; TypeModel.TestEnumerableListPatterns(model, candidates, iType); } } PropertyInfo[] properties = listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int k = 0; k < properties.Length; k++) { PropertyInfo indexer = properties[k]; if (!(indexer.Name != "Item") && !candidates.Contains(indexer.PropertyType)) { ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length == 1 && !(args[0].ParameterType != model.MapType(typeof(int)))) { candidates.Add(indexer.PropertyType); } } } switch (candidates.Count) { case 0: return(null); case 1: return((Type)candidates[0]); case 2: if (TypeModel.CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1])) { return((Type)candidates[0]); } if (TypeModel.CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0])) { return((Type)candidates[1]); } break; } return(null); }
public override string GetSchema(Type type) { BasicList requiredTypes = new BasicList(); MetaType primaryType = null; bool isInbuiltType = false; if (type == null) { BasicList.NodeEnumerator enumerator = this.types.GetEnumerator(); while (enumerator.MoveNext()) { MetaType meta = (MetaType)enumerator.Current; MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false); if (!requiredTypes.Contains(tmp)) { requiredTypes.Add(tmp); this.CascadeDependents(requiredTypes, tmp); } } } else { Type tmp2 = Helpers.GetUnderlyingType(type); if (tmp2 != null) { type = tmp2; } WireType defaultWireType; isInbuiltType = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false) != null); if (!isInbuiltType) { int index = this.FindOrAddAuto(type, false, false, false); if (index < 0) { throw new ArgumentException("The type specified is not a contract-type", "type"); } primaryType = ((MetaType)this.types[index]).GetSurrogateOrBaseOrSelf(false); requiredTypes.Add(primaryType); this.CascadeDependents(requiredTypes, primaryType); } } StringBuilder headerBuilder = new StringBuilder(); string package = null; if (!isInbuiltType) { IEnumerable typesForNamespace = (primaryType == null) ? this.types : requiredTypes; foreach (MetaType meta2 in typesForNamespace) { if (!meta2.IsList) { string tmp3 = meta2.Type.Namespace; if (!Helpers.IsNullOrEmpty(tmp3) && !tmp3.StartsWith("System.")) { if (package == null) { package = tmp3; } else { if (!(package == tmp3)) { package = null; break; } } } } } } if (!Helpers.IsNullOrEmpty(package)) { headerBuilder.Append("package ").Append(package).Append(';'); Helpers.AppendLine(headerBuilder); } bool requiresBclImport = false; StringBuilder bodyBuilder = new StringBuilder(); MetaType[] metaTypesArr = new MetaType[requiredTypes.Count]; requiredTypes.CopyTo(metaTypesArr, 0); Array.Sort <MetaType>(metaTypesArr, MetaType.Comparer.Default); if (isInbuiltType) { Helpers.AppendLine(bodyBuilder).Append("message ").Append(type.Name).Append(" {"); MetaType.NewLine(bodyBuilder, 1).Append("optional ").Append(this.GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport)).Append(" value = 1;"); Helpers.AppendLine(bodyBuilder).Append('}'); } else { for (int i = 0; i < metaTypesArr.Length; i++) { MetaType tmp4 = metaTypesArr[i]; if (!tmp4.IsList || tmp4 == primaryType) { tmp4.WriteSchema(bodyBuilder, 0, ref requiresBclImport); } } } if (requiresBclImport) { headerBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types"); Helpers.AppendLine(headerBuilder); } return(Helpers.AppendLine(headerBuilder.Append(bodyBuilder)).ToString()); }