/// 引用解析器 /// 处理复杂嵌套类型和循环引用检测 library; import 'package:logging/logging.dart'; import 'package:swagger_generator_flutter/core/models.dart'; /// 引用解析器 /// 负责处理 OpenAPI 文档中的复杂引用关系 class ReferenceResolver { ReferenceResolver({this.maxDepth = 50}); static final Logger _logger = Logger('ReferenceResolver'); /// 已解析的模型缓存 final Map _resolvedModels = {}; /// 当前解析路径(用于循环引用检测) final Set _resolutionPath = {}; /// 原始 JSON 数据缓存 final Map> _rawSchemas = {}; /// 最大解析深度(防止过深的嵌套) final int maxDepth; /// 当前解析深度 int _currentDepth = 0; /// 解析所有模型,处理复杂引用关系 Map resolveModels(Map componentsJson) { final schemasJson = componentsJson['schemas'] as Map? ?? {}; // 第一步:缓存所有原始 schema 数据 _cacheRawSchemas(schemasJson); // 第二步:解析所有模型 final resolvedModels = {}; for (final schemaName in schemasJson.keys) { try { final model = resolveModel(schemaName); if (model != null) { resolvedModels[schemaName] = model; } } on Object catch (e) { _logger.warning('⚠️ 解析模型 $schemaName 时发生错误: $e'); // 创建一个基本的模型作为后备 resolvedModels[schemaName] = ApiModel( name: schemaName, description: '解析失败的模型', properties: {}, required: [], ); } } return resolvedModels; } /// 缓存原始 schema 数据 void _cacheRawSchemas(Map schemasJson) { schemasJson.forEach((name, schemaData) { if (schemaData is Map) { _rawSchemas[name] = schemaData; } }); } /// 解析单个模型 ApiModel? resolveModel(String modelName) { // 检查是否已经解析过 if (_resolvedModels.containsKey(modelName)) { return _resolvedModels[modelName]; } // 检查循环引用 if (_resolutionPath.contains(modelName)) { _logger .warning('🔄 检测到循环引用: ${_resolutionPath.join(' -> ')} -> $modelName'); return _createCircularReferenceModel(modelName); } // 检查解析深度 if (_currentDepth >= maxDepth) { _logger.warning('⚠️ 达到最大解析深度 $maxDepth,停止解析 $modelName'); return _createDepthLimitModel(modelName); } // 获取原始数据 final schemaData = _rawSchemas[modelName]; if (schemaData == null) { _logger.warning('⚠️ 未找到模型定义: $modelName'); return null; } // 开始解析 _resolutionPath.add(modelName); _currentDepth++; try { final model = _parseModelWithContext(modelName, schemaData); _resolvedModels[modelName] = model; return model; } finally { _resolutionPath.remove(modelName); _currentDepth--; } } /// 在上下文中解析模型 ApiModel _parseModelWithContext(String name, Map json) { // 检查是否是枚举类型 final isEnum = json['enum'] != null; if (isEnum) { return _parseEnumModel(name, json); } // 检查组合模式 if (json['allOf'] != null || json['oneOf'] != null || json['anyOf'] != null) { return _parseCompositionModel(name, json); } // 解析普通对象模型 return _parseObjectModel(name, json); } /// 解析枚举模型 ApiModel _parseEnumModel(String name, Map json) { final enumValues = List.from((json['enum'] as List?) ?? []); final enumType = PropertyType.fromString(json['type'] as String? ?? 'string'); return ApiModel( name: name, description: json['description'] as String? ?? '', properties: {}, required: [], isEnum: true, enumValues: enumValues, enumType: enumType, ); } /// 解析组合模式模型 ApiModel _parseCompositionModel(String name, Map json) { // 解析组合模式 final allOf = _parseSchemaList(json['allOf'] as List? ?? []); final oneOf = _parseSchemaList(json['oneOf'] as List? ?? []); final anyOf = _parseSchemaList(json['anyOf'] as List? ?? []); final notJson = json['not'] as Map?; final not = notJson != null ? ApiSchema.fromJson(notJson) : null; // 解析 discriminator final discriminatorJson = json['discriminator'] as Map?; final discriminator = discriminatorJson != null ? ApiDiscriminator.fromJson(discriminatorJson) : null; // 对于组合模式,我们需要合并属性 final mergedProperties = {}; final mergedRequired = []; // 从 allOf 中合并属性 for (final schema in allOf) { _mergeSchemaProperties(schema, mergedProperties, mergedRequired); } // 如果有直接的 properties,也要合并 if (json['properties'] != null) { final directProperties = _parseProperties( json['properties'] as Map, List.from((json['required'] as List?) ?? []), ); mergedProperties.addAll(directProperties); mergedRequired .addAll(List.from((json['required'] as List?) ?? [])); } return ApiModel( name: name, description: json['description'] as String? ?? '', properties: mergedProperties, required: mergedRequired.toSet().toList(), allOf: allOf, oneOf: oneOf, anyOf: anyOf, not: not, discriminator: discriminator, ); } /// 解析对象模型 ApiModel _parseObjectModel(String name, Map json) { final properties = _parseProperties( json['properties'] as Map? ?? {}, List.from((json['required'] as List?) ?? []), ); final required = List.from((json['required'] as List?) ?? []); return ApiModel( name: name, description: json['description'] as String? ?? '', properties: properties, required: required, ); } /// 解析 schema 列表 List _parseSchemaList(List schemaList) { return schemaList .map((schema) => ApiSchema.fromJson(schema as Map)) .toList(); } /// 合并 schema 的属性 void _mergeSchemaProperties( ApiSchema schema, Map targetProperties, List targetRequired, ) { // 如果是引用,解析引用的模型 if (schema.isReference && schema.reference != null) { final referencedModel = resolveModel(schema.reference!); if (referencedModel != null) { targetProperties.addAll(referencedModel.properties); targetRequired.addAll(referencedModel.required); } } else { // 直接合并属性 targetProperties.addAll(schema.properties); targetRequired.addAll(schema.required); } } /// 解析属性 Map _parseProperties( Map propertiesJson, List requiredFields, ) { final properties = {}; propertiesJson.forEach((propName, propData) { if (propData is Map) { try { final property = _parsePropertyWithContext(propName, propData, requiredFields); properties[propName] = property; } on Object catch (e) { _logger.warning('⚠️ 解析属性 $propName 时发生错误: $e'); // 创建一个基本属性作为后备 properties[propName] = ApiProperty( name: propName, type: PropertyType.string, description: '解析失败的属性', required: requiredFields.contains(propName), ); } } }); return properties; } /// 在上下文中解析属性 ApiProperty _parsePropertyWithContext( String name, Map json, List requiredFields, ) { // 使用现有的 ApiProperty.fromJson,但在循环引用检测的上下文中 return ApiProperty.fromJson(name, json, requiredFields); } /// 创建循环引用模型 ApiModel _createCircularReferenceModel(String modelName) { return ApiModel( name: modelName, description: '循环引用模型 - 为避免无限递归而创建的占位符', properties: {}, required: [], ); } /// 创建深度限制模型 ApiModel _createDepthLimitModel(String modelName) { return ApiModel( name: modelName, description: '深度限制模型 - 达到最大解析深度而创建的占位符', properties: {}, required: [], ); } /// 清理缓存 void clearCache() { _resolvedModels.clear(); _resolutionPath.clear(); _rawSchemas.clear(); _currentDepth = 0; } }