use of com.google.api.codegen.samplegen.v1p2.SampleConfigProto in project toolkit by googleapis.
the class GapicGeneratorApp method process.
@Override
protected void process() throws Exception {
String protoPackage = Strings.emptyToNull(options.get(PROTO_PACKAGE));
// Read the GAPIC config, if it was given, and convert it to proto.
List<String> configFileNames = options.get(GENERATOR_CONFIG_FILES);
ConfigProto configProto = null;
if (configFileNames.size() > 0) {
// Read the YAML config and convert it to proto.
ConfigSource configSource = loadConfigFromFiles(configFileNames, ConfigProto.getDescriptor().getFullName(), ConfigProto.getDefaultInstance());
if (configSource == null) {
return;
}
configProto = (ConfigProto) configSource.getConfig();
if (configProto == null) {
return;
}
}
// Consume gRPC Service Config if it is given with gapic_v2.
String gRPCServiceConfigPath = options.get(GRPC_SERVICE_CONFIG);
ServiceConfig gRPCServiceConfig = null;
if (!Strings.isNullOrEmpty(gRPCServiceConfigPath) && configProto.getConfigSchemaVersion().equals("2.0.0")) {
ServiceConfig.Builder builder = ServiceConfig.newBuilder();
FileReader file = new FileReader(gRPCServiceConfigPath);
JsonFormat.parser().merge(file, builder);
gRPCServiceConfig = builder.build();
}
// Read the sample configs, if they are given, and convert them to protos.
SampleConfigProto sampleConfigProto = null;
List<String> sampleConfigFileNames = options.get(SAMPLE_CONFIG_FILES);
if (sampleConfigFileNames.size() > 0) {
ConfigSource configSource = loadConfigFromFiles(SampleConfigSanitizer.sanitize(sampleConfigFileNames), SampleConfigProto.getDescriptor().getFullName(), SampleConfigProto.getDefaultInstance());
// TODO(hzyi): Verify this works for repeated fields as well
// TODO(hzyi): Allow users to put arbitrary top-level directives not
// used by gapic-generator
sampleConfigProto = (SampleConfigProto) configSource.getConfig();
}
model.establishStage(Merged.KEY);
if (model.getDiagReporter().getDiagCollector().getErrorCount() > 0) {
for (Diag diag : model.getDiagReporter().getDiagCollector().getDiags()) {
System.err.println(diag.toString());
}
return;
}
ApiDefaultsConfig apiDefaultsConfig = ApiDefaultsConfig.load();
DependenciesConfig dependenciesConfig = DependenciesConfig.load();
TargetLanguage language;
if (!Strings.isNullOrEmpty(options.get(LANGUAGE))) {
language = TargetLanguage.fromString(options.get(LANGUAGE).toUpperCase());
} else {
throw new IllegalArgumentException("Language not set by --language option.");
}
String clientPackage = Strings.emptyToNull(options.get(CLIENT_PACKAGE));
String transport = options.get(TRANSPORT).toLowerCase();
TransportProtocol tp;
if (transport.equals("grpc")) {
tp = TransportProtocol.GRPC;
} else if (transport.equals("rest")) {
tp = TransportProtocol.HTTP;
} else {
throw new IllegalArgumentException("Unknown transport protocol: " + transport);
}
GapicProductConfig productConfig = GapicProductConfig.create(model, configProto, sampleConfigProto, protoPackage, clientPackage, language, gRPCServiceConfig, tp);
if (productConfig == null) {
ToolUtil.reportDiags(model.getDiagReporter().getDiagCollector(), true);
return;
}
PackagingConfig packagingConfig;
if (!Strings.isNullOrEmpty(options.get(PACKAGE_CONFIG2_FILE))) {
packagingConfig = PackagingConfig.load(options.get(PACKAGE_CONFIG2_FILE));
} else {
packagingConfig = PackagingConfig.loadFromProductConfig(productConfig.getInterfaceConfigMap());
}
PackageMetadataConfig packageConfig = PackageMetadataConfig.createFromPackaging(apiDefaultsConfig, dependenciesConfig, packagingConfig);
// TODO(hzyi-google): Once we switch to sample configs, require an
// additional check to generate samples:
// `sampleConfigProto != null`
ArtifactFlags artifactFlags = new ArtifactFlags(options.get(ENABLED_ARTIFACTS), artifactType, options.get(DEV_SAMPLES));
List<CodeGenerator<?>> generators = GapicGeneratorFactory.create(language, model, productConfig, packageConfig, artifactFlags);
ImmutableMap.Builder<String, GeneratedResult<?>> generatedResults = ImmutableMap.builder();
for (CodeGenerator<?> generator : generators) {
Map<String, ? extends GeneratedResult<?>> generatorResult = generator.generate();
for (Map.Entry<String, ? extends GeneratedResult<?>> entry : generatorResult.entrySet()) {
generatedResults.put(entry.getKey(), entry.getValue());
}
}
gapicWriter.writeCodeGenOutput(generatedResults.build(), model.getDiagReporter().getDiagCollector());
}
use of com.google.api.codegen.samplegen.v1p2.SampleConfigProto 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.codegen.samplegen.v1p2.SampleConfigProto in project toolkit by googleapis.
the class CodegenTestUtil method readSampleConfig.
public static SampleConfigProto readSampleConfig(DiagCollector diagCollector, TestDataLocator testDataLocator, String[] sampleConfigFileNames) {
ImmutableMap<String, Message> supportedConfigTypes = ImmutableMap.of(SampleConfigProto.getDescriptor().getFullName(), SampleConfigProto.getDefaultInstance());
List<String> configFilePaths = new ArrayList<>();
List<File> configFiles = new ArrayList<>();
for (String sampleConfigFileName : sampleConfigFileNames) {
URL sampleConfigUrl = testDataLocator.findTestData(sampleConfigFileName);
String sampleConfigPath = Objects.requireNonNull(sampleConfigUrl).getPath();
configFilePaths.add(sampleConfigPath);
}
for (String sampleConfigPath : SampleConfigSanitizer.sanitize(configFilePaths)) {
File configFile = new File(sampleConfigPath);
configFiles.add(configFile);
}
ConfigSource configSource = MultiYamlReader.read(diagCollector, configFiles, supportedConfigTypes);
if (diagCollector.getErrorCount() > 0) {
System.err.println(diagCollector.toString());
return null;
}
return (SampleConfigProto) configSource.getConfig();
}
use of com.google.api.codegen.samplegen.v1p2.SampleConfigProto in project toolkit by googleapis.
the class SampleConfig method createSampleConfigTable.
public static ImmutableTable<String, String, ImmutableList<SampleConfig>> createSampleConfigTable(@Nullable SampleConfigProto sampleConfigProto, final Map<String, InterfaceConfig> interfaceConfigMap) {
if (sampleConfigProto == null) {
sampleConfigProto = SampleConfigProto.getDefaultInstance();
}
// First, apply region tag as IDs if IDs are not given
List<SampleSpecProto> sampleSpecs = new ArrayList<>();
for (SampleSpecProto spec : sampleConfigProto.getSamplesList()) {
if (spec.getId().isEmpty()) {
spec = spec.toBuilder().setId(spec.getRegionTag()).build();
}
sampleSpecs.add(spec);
}
// Then, check user specified sample IDs do not clash
Set<String> distinctIds = new HashSet<>();
Set<String> duplicateIds = sampleSpecs.stream().map(s -> s.getId()).filter(id -> !id.isEmpty()).filter(s -> !distinctIds.add(s)).collect(Collectors.toSet());
Preconditions.checkArgument(duplicateIds.isEmpty(), "Found duplicate IDs: %s", duplicateIds.stream().collect(Collectors.joining(", ")));
// Next, flatten the calling pattern list so we have one per sample
// Note these are not the final calling pattern values, because the
// regexes specified in the config need to be matched against
// language-specific calling pattern definitions.
List<SampleSpecProto> flattenedSampleSpecs = new ArrayList<>();
for (SampleSpecProto spec : sampleSpecs) {
if (spec.getCallingPatternsList().isEmpty()) {
flattenedSampleSpecs.add(spec.toBuilder().addCallingPatterns(DEFAULT_CALLING_PATTERN).build());
}
for (String pattern : spec.getCallingPatternsList()) {
flattenedSampleSpecs.add(spec.toBuilder().clearCallingPatterns().addCallingPatterns(pattern).build());
}
}
// Construct the table.
HashBasedTable<String, String, ArrayList<SampleConfig>> table = HashBasedTable.create();
for (SampleSpecProto sampleSpec : flattenedSampleSpecs) {
SampleConfig config = createOneSampleConfig(sampleSpec, interfaceConfigMap);
if (!table.contains(sampleSpec.getService(), sampleSpec.getRpc())) {
table.put(sampleSpec.getService(), sampleSpec.getRpc(), new ArrayList<>());
}
table.get(sampleSpec.getService(), sampleSpec.getRpc()).add(config);
}
// Make an immutable copy.
return table.cellSet().stream().collect(ImmutableTable.toImmutableTable(Table.Cell::getRowKey, Table.Cell::getColumnKey, v -> ImmutableList.copyOf(v.getValue())));
}
Aggregations