/** * Checks for updates to the server's mutable services and updates the index if any changes are * detected. A change is any addition or removal in the set of file descriptors attached to the * mutable services or a change in the service names. * * @return The (potentially updated) index. */ private ServerReflectionIndex updateIndexIfNecessary() { synchronized (lock) { if (serverReflectionIndex == null) { serverReflectionIndex = new ServerReflectionIndex(server.getImmutableServices(), server.getMutableServices()); return serverReflectionIndex; } Set<FileDescriptor> serverFileDescriptors = new HashSet<FileDescriptor>(); Set<String> serverServiceNames = new HashSet<String>(); List<ServerServiceDefinition> serverMutableServices = server.getMutableServices(); for (ServerServiceDefinition mutableService : serverMutableServices) { io.grpc.ServiceDescriptor serviceDescriptor = mutableService.getServiceDescriptor(); if (serviceDescriptor.getSchemaDescriptor() instanceof ProtoFileDescriptorSupplier) { String serviceName = serviceDescriptor.getName(); FileDescriptor fileDescriptor = ((ProtoFileDescriptorSupplier) serviceDescriptor.getSchemaDescriptor()) .getFileDescriptor(); serverFileDescriptors.add(fileDescriptor); serverServiceNames.add(serviceName); } } // Replace the index if the underlying mutable services have changed. Check both the file // descriptors and the service names, because one file descriptor can define multiple // services. FileDescriptorIndex mutableServicesIndex = serverReflectionIndex.getMutableServicesIndex(); if (!mutableServicesIndex.getServiceFileDescriptors().equals(serverFileDescriptors) || !mutableServicesIndex.getServiceNames().equals(serverServiceNames)) { serverReflectionIndex = new ServerReflectionIndex(server.getImmutableServices(), serverMutableServices); } return serverReflectionIndex; } }
FileDescriptorIndex(List<ServerServiceDefinition> services) { Queue<FileDescriptor> fileDescriptorsToProcess = new ArrayDeque<FileDescriptor>(); Set<String> seenFiles = new HashSet<String>(); for (ServerServiceDefinition service : services) { io.grpc.ServiceDescriptor serviceDescriptor = service.getServiceDescriptor(); if (serviceDescriptor.getSchemaDescriptor() instanceof ProtoFileDescriptorSupplier) { FileDescriptor fileDescriptor = ((ProtoFileDescriptorSupplier) serviceDescriptor.getSchemaDescriptor()) .getFileDescriptor(); String serviceName = serviceDescriptor.getName(); checkState( !serviceNames.contains(serviceName), "Service already defined: %s", serviceName); serviceFileDescriptors.add(fileDescriptor); serviceNames.add(serviceName); if (!seenFiles.contains(fileDescriptor.getName())) { seenFiles.add(fileDescriptor.getName()); fileDescriptorsToProcess.add(fileDescriptor); } } } while (!fileDescriptorsToProcess.isEmpty()) { FileDescriptor currentFd = fileDescriptorsToProcess.remove(); processFileDescriptor(currentFd); for (FileDescriptor dependencyFd : currentFd.getDependencies()) { if (!seenFiles.contains(dependencyFd.getName())) { seenFiles.add(dependencyFd.getName()); fileDescriptorsToProcess.add(dependencyFd); } } } }