use of com.google.api.ResourceReference in project toolkit by googleapis.
the class GapicProductConfig method create.
/**
* Creates an instance of GapicProductConfig based on ConfigProto, linking up API interface
* configurations with specified interfaces in interfaceConfigMap. On errors, null will be
* returned, and diagnostics are reported to the model.
*
* @param model The protobuf model for which we are creating a config.
* @param configProto The parsed set of library config files from input
* @param sampleConfigProto The parsed set of sample config files from the input
* @param protoPackage The source proto package, as opposed to imported protos, that we will
* generate clients for.
* @param clientPackage The desired package name for the generated client.
* @param language The language that this config will be used to generate a client in.
* @param grpcServiceConfig Method retries configuration.
* @param transportProtocol Transport protocol to support.
*/
@Nullable
public static GapicProductConfig create(Model model, @Nullable ConfigProto configProto, @Nullable SampleConfigProto sampleConfigProto, @Nullable String protoPackage, @Nullable String clientPackage, TargetLanguage language, @Nullable ServiceConfig grpcServiceConfig, TransportProtocol transportProtocol) {
final String defaultPackage;
SymbolTable symbolTable = model.getSymbolTable();
if (protoPackage != null) {
// Default to using --package option for value of default package and first API protoFile.
defaultPackage = protoPackage;
} else if (configProto != null && configProto.getInterfacesCount() > 0) {
// Otherwise use configProto to get the proto file containing the first interface listed in
// the config proto, and use it as the assigned file for generated resource names, and to get
// the default message namespace.
ProtoFile file = symbolTable.lookupInterface(configProto.getInterfaces(0).getName()).getFile();
defaultPackage = file.getProto().getPackage();
} else {
throw new NullPointerException("configProto and protoPackage cannot both be null. " + "If using artman, please add the proto_package field to artman config, " + "or switch to bazel.");
}
// Consider all proto files in the defaultPackage as well as its sub-packages
// as source files.
List<ProtoFile> sourceProtos = model.getFiles().stream().filter(f -> f.getProto().getPackage().startsWith(defaultPackage)).collect(Collectors.toList());
if (protoPackage != null && configProto == null) {
if (sourceProtos.isEmpty()) {
model.getDiagReporter().getDiagCollector().addDiag(Diag.error(SimpleLocation.TOPLEVEL, "There are no source proto files with package %s", defaultPackage));
}
sourceProtos.forEach(model::addRoot);
}
// Toggle on/off proto annotations parsing.
ProtoParser protoParser;
ConfigVersionValidator versionValidator = new ConfigVersionValidator();
if (versionValidator.isV2Config(configProto)) {
versionValidator.validateV2Config(configProto);
protoParser = new ProtoParser(true);
if (configProto == null) {
configProto = ConfigProto.getDefaultInstance();
}
} else {
protoParser = new ProtoParser(false);
}
DiagCollector diagCollector = model.getDiagReporter().getDiagCollector();
ProtoFile packageProtoFile = sourceProtos.isEmpty() ? null : sourceProtos.get(0);
ImmutableMap<String, ResourceNameConfig> resourceNameConfigs;
ResourceNameMessageConfigs messageConfigs;
if (protoParser.isProtoAnnotationsEnabled()) {
Map<String, ResourceDescriptorConfig> descriptorConfigMap = protoParser.getResourceDescriptorConfigMap(model.getFiles(), diagCollector);
List<ResourceReference> fieldsWithResourceRefs = sourceProtos.stream().flatMap(protoFile -> protoFile.getMessages().stream()).flatMap(messageType -> messageType.getFields().stream()).filter(protoParser::hasResourceReference).map(protoParser::getResourceReference).collect(Collectors.toList());
Set<String> configsWithChildTypeReferences = fieldsWithResourceRefs.stream().map(ResourceReference::getChildType).filter(t -> !Strings.isNullOrEmpty(t)).collect(Collectors.toSet());
Set<String> configsWithTypeReferences = fieldsWithResourceRefs.stream().map(ResourceReference::getType).filter(t -> !Strings.isNullOrEmpty(t)).collect(Collectors.toSet());
Map<String, DeprecatedCollectionConfigProto> deprecatedPatternResourceMap = configProto.getInterfacesList().stream().flatMap(i -> i.getDeprecatedCollectionsList().stream()).distinct().collect(ImmutableMap.toImmutableMap(DeprecatedCollectionConfigProto::getNamePattern, c -> c));
// Create a pattern-to-resource map to make looking up parent resources easier.
Map<String, List<ResourceDescriptorConfig>> patternResourceDescriptorMap = ResourceDescriptorConfig.getPatternResourceMap(descriptorConfigMap.values());
// Create a child-to-parent map to make resolving child_type easier.
Map<String, List<ResourceDescriptorConfig>> childParentResourceMap = ResourceDescriptorConfig.getChildParentResourceMap(descriptorConfigMap, patternResourceDescriptorMap);
resourceNameConfigs = createResourceNameConfigsFromAnnotationsAndGapicConfig(model, diagCollector, configProto, packageProtoFile, language, descriptorConfigMap, configsWithTypeReferences, configsWithChildTypeReferences, deprecatedPatternResourceMap, patternResourceDescriptorMap, childParentResourceMap, defaultPackage);
messageConfigs = ResourceNameMessageConfigs.createFromAnnotations(diagCollector, model.getFiles(), resourceNameConfigs, protoParser, descriptorConfigMap, childParentResourceMap);
} else {
resourceNameConfigs = createResourceNameConfigsFromGapicConfigOnly(model, diagCollector, configProto, packageProtoFile, language);
messageConfigs = ResourceNameMessageConfigs.createFromGapicConfigOnly(sourceProtos, configProto, defaultPackage);
}
if (resourceNameConfigs == null) {
return null;
}
String clientPackageName;
LanguageSettingsProto settings = configProto.getLanguageSettingsMap().get(language.toString().toLowerCase());
if (settings == null) {
settings = LanguageSettingsProto.getDefaultInstance();
if (!Strings.isNullOrEmpty(clientPackage)) {
clientPackageName = clientPackage;
} else {
String basePackageName = Optional.ofNullable(protoPackage).orElse(getPackageName(model));
clientPackageName = LanguageSettingsMerger.getFormattedPackageName(language, basePackageName);
}
} else {
clientPackageName = settings.getPackageName();
}
ImmutableMap<String, Interface> protoInterfaces = getInterfacesFromProtoFile(diagCollector, sourceProtos, symbolTable);
ImmutableList<GapicInterfaceInput> interfaceInputs;
if (protoParser.isProtoAnnotationsEnabled()) {
interfaceInputs = createInterfaceInputsWithAnnotationsAndGapicConfig(diagCollector, configProto.getInterfacesList(), protoInterfaces, language);
} else {
interfaceInputs = createInterfaceInputsWithGapicConfigOnly(diagCollector, configProto.getInterfacesList(), protoInterfaces, symbolTable, language);
}
if (interfaceInputs == null) {
return null;
}
GrpcGapicRetryMapping grpcGapicRetryMapping = null;
if (grpcServiceConfig != null) {
grpcGapicRetryMapping = GrpcGapicRetryMapping.create(grpcServiceConfig, protoInterfaces);
}
ImmutableMap<String, InterfaceConfig> interfaceConfigMap = createInterfaceConfigMap(diagCollector, interfaceInputs, defaultPackage, settings, messageConfigs, resourceNameConfigs, language, transportProtocol, protoParser, grpcGapicRetryMapping);
ImmutableList<String> copyrightLines;
ImmutableList<String> licenseLines;
String configSchemaVersion = null;
LicenseHeaderUtil licenseHeaderUtil = new LicenseHeaderUtil();
try {
copyrightLines = licenseHeaderUtil.loadCopyrightLines();
licenseLines = licenseHeaderUtil.loadLicenseLines();
} catch (Exception e) {
model.getDiagReporter().getDiagCollector().addDiag(Diag.error(SimpleLocation.TOPLEVEL, "Exception: %s", e.getMessage()));
e.printStackTrace(System.err);
throw new RuntimeException(e);
}
if (!configProto.equals(ConfigProto.getDefaultInstance())) {
configSchemaVersion = configProto.getConfigSchemaVersion();
if (Strings.isNullOrEmpty(configSchemaVersion)) {
model.getDiagReporter().getDiagCollector().addDiag(Diag.error(SimpleLocation.TOPLEVEL, "config_schema_version field is required in GAPIC yaml."));
}
}
Boolean enableStringFormatFunctionsOverride = null;
if (configProto.hasEnableStringFormatFunctionsOverride()) {
enableStringFormatFunctionsOverride = configProto.getEnableStringFormatFunctionsOverride().getValue();
}
if (interfaceConfigMap == null || copyrightLines == null || licenseLines == null) {
return null;
}
return new AutoValue_GapicProductConfig(interfaceConfigMap, clientPackageName, settings.getDomainLayerLocation(), settings.getReleaseLevel(), messageConfigs, copyrightLines, licenseLines, resourceNameConfigs, protoParser, transportProtocol, createResponseFieldConfigMap(messageConfigs, resourceNameConfigs), configSchemaVersion, enableStringFormatFunctionsOverride, SampleConfig.createSampleConfigTable(sampleConfigProto, interfaceConfigMap), new Date());
}
use of com.google.api.ResourceReference in project toolkit by googleapis.
the class ResourceNameMessageConfigs method loadFieldEntityPairFromResourceReferenceAnnotation.
/**
* Create field name to resource name type mappings from (google.api).resource_reference
* annotations and put them to fieldEntityMap.
*/
private static void loadFieldEntityPairFromResourceReferenceAnnotation(ImmutableListMultimap.Builder<String, String> fieldEntityMap, ProtoParser parser, MessageType message, Map<String, ResourceNameConfig> resourceNameConfigs, Map<String, ResourceDescriptorConfig> descriptorConfigMap, Map<String, List<ResourceDescriptorConfig>> childParentResourceMap) {
for (Field field : message.getFields()) {
ResourceReference reference = parser.getResourceReference(field);
if (reference == null) {
continue;
}
String childType = reference.getChildType();
String type = reference.getType();
Preconditions.checkArgument(childType.isEmpty() || type.isEmpty(), "At least one of child_type and type should be set: %s", field);
Preconditions.checkArgument(!childType.isEmpty() || !type.isEmpty(), "Only one of child_type and type should be set: %s", field);
if (type.equals("*") || childType.equals("*")) {
fieldEntityMap.put(field.getSimpleName(), "*");
continue;
}
List<ResourceDescriptorConfig> referencedResources;
if (!childType.isEmpty()) {
referencedResources = childParentResourceMap.get(childType);
checkNotNull(referencedResources, "unable to find parent resources of %s", childType);
} else {
ResourceDescriptorConfig referencedResource = descriptorConfigMap.get(type);
checkNotNull(referencedResource, "unable to find referenced resource %s", type);
referencedResources = Collections.singletonList(referencedResource);
}
for (ResourceDescriptorConfig descriptor : referencedResources) {
String unqualifiedName = descriptor.getDerivedEntityName();
ResourceNameConfig resource = resourceNameConfigs.get(unqualifiedName);
switch(resource.getResourceNameType()) {
case ANY:
fieldEntityMap.put(field.getSimpleName(), "*");
break;
case SINGLE:
fieldEntityMap.put(field.getSimpleName(), unqualifiedName);
break;
case ONEOF:
fieldEntityMap.put(field.getSimpleName(), unqualifiedName);
if (((ResourceNameOneofConfig) resource).hasAnyResourceNamePattern()) {
fieldEntityMap.put(field.getSimpleName(), "*");
}
break;
default:
throw new IllegalArgumentException("unknown resource name type: " + resource.getResourceNameType());
}
}
}
}
Aggregations