@@ -116,6 +116,9 @@ def resolve_imports(
116116
117117 visited .add (file_path )
118118
119+ if file_path .suffix == ".proto" :
120+ return _resolve_proto_imports (file_path , import_paths , visited , cache )
121+
119122 # Parse the file
120123 schema = parse_idl_file (file_path )
121124
@@ -167,6 +170,77 @@ def resolve_imports(
167170 return merged_schema
168171
169172
173+ def _resolve_proto_imports (
174+ file_path : Path ,
175+ import_paths : Optional [List [Path ]],
176+ visited : Set [Path ],
177+ cache : Dict [Path , Schema ],
178+ ) -> Schema :
179+ """Proto-specific import resolution."""
180+ from fory_compiler .frontend .proto import ProtoFrontend
181+
182+ frontend = ProtoFrontend ()
183+ source = file_path .read_text ()
184+ proto_schema = frontend .parse_ast (source , str (file_path ))
185+ direct_import_proto_schemas = []
186+ imported_enums = []
187+ imported_messages = []
188+ imported_unions = []
189+ imported_services = []
190+ file_packages : Dict [str , Optional [str ]] = {
191+ str (file_path ): proto_schema .package
192+ } # file -> the package it belongs.
193+
194+ for imp_path_str in proto_schema .imports :
195+ import_path = resolve_import_path (imp_path_str , file_path , import_paths or [])
196+ if import_path is None :
197+ searched = [str (file_path .parent )]
198+ if import_paths :
199+ searched .extend (str (p ) for p in import_paths )
200+ raise ImportError (
201+ f"Import not found: { imp_path_str } \n Searched in: { ', ' .join (searched )} "
202+ )
203+ imp_source = import_path .read_text ()
204+ imp_proto_ast = frontend .parse_ast (imp_source , str (import_path ))
205+ direct_import_proto_schemas .append (imp_proto_ast )
206+
207+ # Recursively resolve the imported file
208+ imported_full = resolve_imports (
209+ import_path , import_paths , visited .copy (), cache
210+ )
211+ imported_enums .extend (imported_full .enums )
212+ imported_messages .extend (imported_full .messages )
213+ imported_unions .extend (imported_full .unions )
214+ imported_services .extend (imported_full .services )
215+
216+ # Collect file->package mappings from the imported schema.
217+ if imported_full .file_packages :
218+ file_packages .update (imported_full .file_packages )
219+ else :
220+ file_packages [str (import_path )] = imported_full .package
221+
222+ schema = frontend .parse_with_imports (
223+ source , str (file_path ), direct_import_proto_schemas
224+ )
225+
226+ merged_schema = Schema (
227+ package = schema .package ,
228+ package_alias = schema .package_alias ,
229+ imports = schema .imports ,
230+ enums = imported_enums + schema .enums ,
231+ messages = imported_messages + schema .messages ,
232+ unions = imported_unions + schema .unions ,
233+ services = imported_services + schema .services ,
234+ options = schema .options ,
235+ source_file = schema .source_file ,
236+ source_format = schema .source_format ,
237+ file_packages = file_packages ,
238+ )
239+
240+ cache [file_path ] = copy .deepcopy (merged_schema )
241+ return merged_schema
242+
243+
170244def go_package_info (schema : Schema ) -> Tuple [Optional [str ], str ]:
171245 """Return (import_path, package_name) for Go."""
172246 go_package = schema .get_option ("go_package" )
0 commit comments