# Path: src/comparator/resource_database.py
# class ResourceDatabase:
#     # Create resource database for file-level and messasge-level resouce definitions.
#     # It has two dictionaries: types map and patterns map. Register a resource will put
#     # [type_str, resource_message] in types dict, and [pattern0, resource_message]
#     # [pattern1, ressource_message] (if it has multiple patterns) in patterns dict."""
#     def __init__(self):
#         self.types = {}
#         self.patterns = {}
# 
#     def register_resource(self, resource_with_location):
#         """Register a resource in the database."""
#         if not resource_with_location or not resource_with_location.value:
#             return
#         resource_message = resource_with_location.value
#         if not resource_message.type or not resource_message.pattern:
#             raise TypeError(
#                 "APIs must define a resource type and resource pattern for each resource in the API."
#             )
#         self.types[resource_message.type] = resource_with_location
#         self.patterns.update(
#             (pattern, resource_with_location) for pattern in resource_message.pattern
#         )
# 
#     def get_resource_by_type(self, resource_type):
#         """Query the resource by type. Return None if the resource is not existing."""
#         return self.types.get(resource_type, None)
# 
#     def get_parent_resources_by_child_type(self, child_type):
#         """Query the resources by child_type. Return [] if the parent resource is not existing."""
#         result = []
#         if not child_type:
#             return result
#         child_resource = self.get_resource_by_type(child_type)
#         # The child_type is not existing in the database.
#         if (
#             not child_resource
#             or not child_resource.value
#             or not child_resource.value.pattern
#         ):
#             return result
#         # For each child_type pattern, split the pattern by '/'
#         # and reconstruct the segments. If any parent pattern is existing
#         # in the database, put it in the result sequence.
#         # For example: `a/{a}` is the parent resource of `a/{a}/b{b}`
#         for child_pattern in child_resource.value.pattern:
#             pattern = ""
#             for segment in child_pattern.split("/"):
#                 if pattern != "":
#                     pattern = pattern + "/"
#                 pattern = pattern + segment
#                 parent = self.get_resource_by_pattern(pattern)
#                 # Check the parent resource is not child_resource itself.
#                 if parent and (parent.value.type != child_resource.value.type):
#                     result.append(parent)
#         return result
# 
#     def get_resource_by_pattern(self, pattern):
#         """Query the resource by pattern. Return None if the resource is not existing."""
#         return self.patterns.get(pattern, None)


import dataclasses
import re
import os
from collections import defaultdict
from google.api import field_behavior_pb2
from google.api import resource_pb2
from google.api import client_pb2
from google.api import annotations_pb2
from google.longrunning import operations_pb2
from google.protobuf import descriptor_pb2
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
from src.comparator.resource_database import ResourceDatabase
from typing import Dict, Sequence, Optional, Tuple, cast, List
            files_by_name[filename] for filename in all_files.difference(imported_files)
        ]
        api_definition_protos = [
            file for file in never_imported if file.package not in COMMON_PACKAGES
        ]
        if len(api_definition_protos) == 0:
            return ""
        return os.path.commonprefix([file.package for file in api_definition_protos])

    def _get_source_code_locations_map(
        self,
    ) -> Dict[str, Dict[Tuple[int, ...], descriptor_pb2.SourceCodeInfo.Location]]:
        source_code_locations_map = {}
        for fd in self.file_set_pb.file:
            if not fd.source_code_info:
                continue
            # Iterate over the source_code_info and place it into a dictionary.
            #
            # The comments in protocol buffers are sorted by a concept called
            # the "path", which is a sequence of integers described in more
            # detail below; this code simply shifts from a list to a dict,
            # with tuples of paths as the dictionary keys.
            source_code_locations = {
                tuple(location.path): location
                for location in fd.source_code_info.location
            }
            source_code_locations_map[fd.name] = source_code_locations
        return source_code_locations_map

    def _get_resource_database(self, files, source_code_locations_map):

# Path: src/comparator/resource_database.py
# class ResourceDatabase:
#     # Create resource database for file-level and messasge-level resouce definitions.
#     # It has two dictionaries: types map and patterns map. Register a resource will put
#     # [type_str, resource_message] in types dict, and [pattern0, resource_message]
#     # [pattern1, ressource_message] (if it has multiple patterns) in patterns dict."""
#     def __init__(self):
#         self.types = {}
#         self.patterns = {}
# 
#     def register_resource(self, resource_with_location):
#         """Register a resource in the database."""
#         if not resource_with_location or not resource_with_location.value:
#             return
#         resource_message = resource_with_location.value
#         if not resource_message.type or not resource_message.pattern:
#             raise TypeError(
#                 "APIs must define a resource type and resource pattern for each resource in the API."
#             )
#         self.types[resource_message.type] = resource_with_location
#         self.patterns.update(
#             (pattern, resource_with_location) for pattern in resource_message.pattern
#         )
# 
#     def get_resource_by_type(self, resource_type):
#         """Query the resource by type. Return None if the resource is not existing."""
#         return self.types.get(resource_type, None)
# 
#     def get_parent_resources_by_child_type(self, child_type):
#         """Query the resources by child_type. Return [] if the parent resource is not existing."""
#         result = []
#         if not child_type:
#             return result
#         child_resource = self.get_resource_by_type(child_type)
#         # The child_type is not existing in the database.
#         if (
#             not child_resource
#             or not child_resource.value
#             or not child_resource.value.pattern
#         ):
#             return result
#         # For each child_type pattern, split the pattern by '/'
#         # and reconstruct the segments. If any parent pattern is existing
#         # in the database, put it in the result sequence.
#         # For example: `a/{a}` is the parent resource of `a/{a}/b{b}`
#         for child_pattern in child_resource.value.pattern:
#             pattern = ""
#             for segment in child_pattern.split("/"):
#                 if pattern != "":
#                     pattern = pattern + "/"
#                 pattern = pattern + segment
#                 parent = self.get_resource_by_pattern(pattern)
#                 # Check the parent resource is not child_resource itself.
#                 if parent and (parent.value.type != child_resource.value.type):
#                     result.append(parent)
#         return result
# 
#     def get_resource_by_pattern(self, pattern):
#         """Query the resource by pattern. Return None if the resource is not existing."""
#         return self.patterns.get(pattern, None)


# Path: src/comparator/wrappers.py
import dataclasses
import re
import os
from collections import defaultdict
from google.api import field_behavior_pb2
from google.api import resource_pb2
from google.api import client_pb2
from google.api import annotations_pb2
from google.longrunning import operations_pb2
from google.protobuf import descriptor_pb2
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
from src.comparator.resource_database import ResourceDatabase
from typing import Dict, Sequence, Optional, Tuple, cast, List

            files_by_name[filename] for filename in all_files.difference(imported_files)
        ]
        api_definition_protos = [
            file for file in never_imported if file.package not in COMMON_PACKAGES
        ]
        if len(api_definition_protos) == 0:
            return ""
        return os.path.commonprefix([file.package for file in api_definition_protos])

    def _get_source_code_locations_map(
        self,
    ) -> Dict[str, Dict[Tuple[int, ...], descriptor_pb2.SourceCodeInfo.Location]]:
        source_code_locations_map = {}
        for fd in self.file_set_pb.file:
            if not fd.source_code_info:
                continue
            # Iterate over the source_code_info and place it into a dictionary.
            #
            # The comments in protocol buffers are sorted by a concept called
            # the "path", which is a sequence of integers described in more
            # detail below; this code simply shifts from a list to a dict,
            # with tuples of paths as the dictionary keys.
            source_code_locations = {
                tuple(location.path): location
                for location in fd.source_code_info.location
            }
            source_code_locations_map[fd.name] = source_code_locations
        return source_code_locations_map

    def _get_resource_database(self, files, source_code_locations_map):

        resources_database = ResourceDatabase()