All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yinxiang.utils.thrift.grpc.operations.CircleDependenciesResolver Maven / Gradle / Ivy

package com.yinxiang.utils.thrift.grpc.operations;

import com.google.common.collect.Sets;
import com.yinxiang.utils.thrift.grpc.infos.FieldType;
import com.yinxiang.utils.thrift.grpc.infos.FileInfo;
import com.yinxiang.utils.thrift.grpc.infos.StructInfo;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * The gRPC proto circle dependencies resolver.
 * 

* Thrift can delimit a import b and b import a, but gRPC can not. * The resolver will change b import a's struct to 'common.proto'. *

* @author Huiyuan Fu * @since 1.0.0 * @see FilesOperation */ public class CircleDependenciesResolver implements FilesOperation { private int resolveCount; @Override public void execute(Map fileInfos) { resolveCount = 0; fileInfos.values().stream().filter(CircleDependenciesResolver::isThriftFile).forEach(fileInfo -> { // get dependencies set Set dependencies = Sets.newHashSet(fileInfo.getDependencies().keySet()); // retain the dependency this proto's set dependencies.retainAll(fileInfo.getDependencyMe()); // change all be depended struct to common file Consumer resolver = dependencyMe -> addDependencyToCommon(fileInfos, dependencyMe, fileInfo); dependencies.forEach(dependency -> { fileInfos.get(dependency).getDependencies().get(fileInfo.getName()).forEach(resolver); fileInfos.get(dependency).getImports().remove(fileInfo.getName()); }); // add import fileInfo.getImports().add(COMMON_FILE); // counter if (dependencies.size() > 0) { resolveCount++; } }); } @Override public void outputLog() { System.out.println("Resolve circle dependencies: " + resolveCount); } /** * Check is origin thrift file. * @param fileInfo proto file info * @return true if is origin thrift file else false */ private static boolean isThriftFile(FileInfo fileInfo) { return !fileInfo.getName().equals(COMMON_FILE) && !fileInfo.getName().equals(ORIGIN_FILE) && !fileInfo.getName().equals(REQUEST_FILE) && !fileInfo.getName().equals(RESPONSE_FILE); } /** * Add dependency to common file. * @param fileInfos map of file info * @param structName dependency struct name * @param sourceFile struct's parent file */ private void addDependencyToCommon(Map fileInfos, String structName, FileInfo sourceFile) { if (sourceFile == null) { return; } // get and remove from source proto file StructInfo structInfo = sourceFile.getStructInfos().remove(structName); // get the common file FileInfo commonFile = fileInfos.get(COMMON_FILE); // get the map of struct from common file Map structInfos = commonFile.getStructInfos(); // put to common file if (structInfo == null) { structInfo = checkNotNull(structInfos.get(structName), structName + " is null."); } else { structInfos.put(structName, structInfo); } // process non-enum if (!structInfo.isEnum()) { // process all field structInfo.getFieldInfos().forEach(fieldInfo -> { addFieldDependencyToCommon(fileInfos, fieldInfo.getFirstType()); addFieldDependencyToCommon(fileInfos, fieldInfo.getSecondType()); }); } } /** * Add a field dependency to common file. * @param fileInfos map of file info * @param fieldType field type */ private void addFieldDependencyToCommon(Map fileInfos, FieldType fieldType) { if (fieldType == null) { return; } String type = fieldType.type; Optional.ofNullable(StructInfo.getFileInfo(type)).ifPresent(file -> addDependencyToCommon(fileInfos, type, file)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy