private void CompleteRuntimeDataType(RuntimeTypeData data) { // At this point, data should have its Type filled in. In case it isn't, let's let an exception bubble up as an error Type netType = data.Type; Dictionary <string, Type> propertyTypes = new Dictionary <string, Type>(); foreach (PropertyInfo pi in netType.GetProperties()) { propertyTypes[pi.Name.ToLowerInvariant()] = pi.PropertyType; } foreach (string propertyName in data.Properties.Keys) { ParameterData propertyData = data.Properties[propertyName]; if (propertyData.Type != null) { // Sometimes the Name property isn't set - propertyName is correct in this case if (String.IsNullOrEmpty(propertyData.Name)) { propertyData.Name = propertyName; } RuntimeTypeData propertyTypeData = propertyData.Type; if (propertyTypeData.Type == null) { // Find the type of this property if (propertyTypes.ContainsKey(propertyName)) { propertyTypeData.Type = propertyTypes[propertyName]; // Recursively fill in the properties of this type CompleteRuntimeDataType(propertyTypeData); } } } } }
private Dictionary <string, ParameterData> GetParameterMetadata(string parameterPath, JsonPathFinder parameter, Dictionary <string, RuntimeTypeData> definitionsCache, Dictionary <string, Dictionary <string, ParameterData> > parameterCache, JsonPathFinder rootDoc) { if (parameterCache.ContainsKey(parameterPath)) { // We've already transformed this parameter into one or more parameters and found the correct module name return(parameterCache[parameterPath]); } Dictionary <string, ParameterData> ret = new Dictionary <string, ParameterData>(); parameterCache[parameterPath] = ret; // 1. Check if it's a ref JsonPathFinder refNode = parameter.Find(new JsonQueryBuilder().Property("$ref")).SingleOrDefault(); if (refNode != null) { // A direct ref should reference a parameter object string refParameterPath = refNode.GetValue <string>(); return(GetParameterMetadata(refParameterPath.ToLowerInvariant(), rootDoc.Find(new JsonQueryBuilder(refParameterPath)).Single(), definitionsCache, parameterCache, rootDoc)); } else { // 2. Get the name and jsonName string jsonName = String.Empty; string clientName = String.Empty; JsonPathFinder jsonNameNode = parameter.Find(new JsonQueryBuilder().Property("name")).SingleOrDefault(); JsonPathFinder clientNameNode = parameter.Find(new JsonQueryBuilder().Property("x-ms-client-name")).SingleOrDefault(); if (jsonNameNode != null) { jsonName = jsonNameNode.GetValue <string>().ToLowerInvariant(); } if (clientNameNode != null) { clientName = clientNameNode.GetValue <string>().ToLowerInvariant(); } // 2. Check if it's a flatten JsonPathFinder flattenNode = parameter.Find(new JsonQueryBuilder().Property("x-ms-client-flatten")).SingleOrDefault(); JsonPathFinder schemaRefNode = parameter.Find(new JsonQueryBuilder().RecursiveDescent().Property("$ref")).SingleOrDefault(); if (flattenNode != null) { // Get the ref node under the schema node - using recursive descent from the parameter node should work // This should be a definitions object string definitionPath = schemaRefNode.GetValue <string>(); RuntimeTypeData definitionData = definitionsCache[definitionPath]; // Don't think there will be a flatten of an object that's just an array? foreach (string propertyName in definitionData.Properties.Keys) { ParameterData data = definitionData.Properties[propertyName]; if (!String.IsNullOrEmpty(data.Name)) { ret[data.Name] = data; } else { ret[data.JsonName] = data; } } } else { // 3. Just a regular parameter - check if it defines a definition as the type ParameterData data = new ParameterData(); data.Name = clientName; data.JsonName = jsonName; if (schemaRefNode != null) { string definitionPath = schemaRefNode.GetValue <string>().ToLowerInvariant(); data.Type = definitionsCache[definitionPath]; } else { // Type with no properties, and the Type itself will be filled in later data.Type = new RuntimeTypeData(); } if (!String.IsNullOrEmpty(clientName)) { ret[clientName] = data; } else { ret[jsonName] = data; } } } return(ret); }