Skip to content

Commit

Permalink
feat(v2): add PRE_MIGRATION_SURFACE_ONLY option (#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahdietz committed Apr 10, 2023
1 parent 1b2af15 commit dc1a2a1
Show file tree
Hide file tree
Showing 73 changed files with 226 additions and 5,427 deletions.
1 change: 1 addition & 0 deletions rules_php_test/integration_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def _php_overwrite_golden_impl(ctx):
golden_update_script_content = """
cd ${{BUILD_WORKSPACE_DIRECTORY}}
# Filename pattern-based removal is needed to preserve the BUILD.bazel file.
find tests/Integration/goldens/{api_name}/ -name \\*.txt -type f -delete
find tests/Integration/goldens/{api_name}/ -name \\*.php -type f -delete
find tests/Integration/goldens/{api_name}/ -name \\*.json -type f -delete
unzip -ao {goldens_output_zip} -d tests/Integration/goldens/{api_name}
Expand Down
63 changes: 33 additions & 30 deletions src/CodeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ public static function generate(
$generateGapicMetadata,
$licenseYear,
$numericEnums,
$generateSnippets,
$migrationMode
$generateSnippets
) as $file) {
$result[] = $file;
}
Expand All @@ -280,11 +279,12 @@ private static function generateServices(
bool $generateGapicMetadata,
int $licenseYear,
bool $numericEnums = false,
bool $generateSnippets = true,
string $migrationMode = MigrationMode::MIGRATION_MODE_UNSPECIFIED
bool $generateSnippets = true
) {
$versionToNamespace = [];
foreach ($servicesToGenerate as $service) {
$migrationMode = $service->migrationMode;

// Look for a version string, "Vn..." as a part of the namespace.
// If found, then the output directories for src and tests use it,
// as can be seen in the 'yield ...' code below.
Expand Down Expand Up @@ -331,7 +331,7 @@ private static function generateServices(
if ($generateSnippets) {
$snippetFiles = SnippetGenerator::generate($licenseYear, $service);

$emptyClientName = $migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED ?
$emptyClientName = $migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED || $migrationMode == MigrationMode::PRE_MIGRATION_SURFACE_ONLY ?
$service->emptyClientType->name :
$service->emptyClientV2Type->name;

Expand All @@ -343,34 +343,37 @@ private static function generateServices(
}

// [Start V2 GAPIC surface generation]
$ctx = new SourceFileContext($service->gapicClientType->getNamespace(), $licenseYear);
$file = GapicClientV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["src/{$version}Client/BaseClient/{$service->gapicClientV2Type->name}.php", $code];
if ($migrationMode != MigrationMode::PRE_MIGRATION_SURFACE_ONLY) {
$ctx = new SourceFileContext($service->gapicClientType->getNamespace(), $licenseYear);
$file = GapicClientV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["src/{$version}Client/BaseClient/{$service->gapicClientV2Type->name}.php", $code];

// Very thin service client wrapper, for manual code additions if required.
$ctx = new SourceFileContext($service->emptyClientV2Type->getNamespace(), $licenseYear);
$file = EmptyClientV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["src/{$version}Client/{$service->emptyClientV2Type->name}.php", $code];
// Very thin service client wrapper, for manual code additions if required.
$ctx = new SourceFileContext($service->emptyClientV2Type->getNamespace(), $licenseYear);
$file = EmptyClientV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["src/{$version}Client/{$service->emptyClientV2Type->name}.php", $code];

// Unit tests.
$ctx = new SourceFileContext($service->unitTestsV2Type->getNamespace(), $licenseYear);
$file = UnitTestsV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["tests/Unit/{$version}Client/{$service->unitTestsV2Type->name}.php", $code];
// Unit tests.
$ctx = new SourceFileContext($service->unitTestsV2Type->getNamespace(), $licenseYear);
$file = UnitTestsV2Generator::generate($ctx, $service);
$code = $file->toCode();
$code = Formatter::format($code);
yield ["tests/Unit/{$version}Client/{$service->unitTestsV2Type->name}.php", $code];


// Resource: build_method.txt
$ctx = new SourceFileContext($service->gapicClientType->getNamespace(), $licenseYear);
$buildMethodFragments = BuildMethodFragmentGenerator::generate($ctx, $service);
foreach ($buildMethodFragments as [$fragmentName, $buildMethodFragment]) {
$buildMethodFragmentCode = BuildMethodFragmentGenerator::format(
$buildMethodFragment->reduce('', fn ($v, $i) => $v . $i->toCode())
);
yield ["fragments/{$fragmentName}.build.txt", $buildMethodFragmentCode];
// Resource: build_method.txt
$ctx = new SourceFileContext($service->gapicClientType->getNamespace(), $licenseYear);
$buildMethodFragments = BuildMethodFragmentGenerator::generate($ctx, $service);
foreach ($buildMethodFragments as [$fragmentName, $buildMethodFragment]) {
$buildMethodFragmentCode = BuildMethodFragmentGenerator::format(
$buildMethodFragment->reduce('', fn ($v, $i) => $v . $i->toCode())
);
yield ["fragments/{$fragmentName}.build.txt", $buildMethodFragmentCode];
}
}
// [End V2 GAPIC surface generation]

Expand Down
54 changes: 35 additions & 19 deletions src/Generation/ResourcesGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Google\Generator\Utils\Helpers;
use Google\Generator\Utils\GapicYamlConfig;
use Google\Generator\Utils\GrpcServiceConfig;
use Google\Generator\Utils\MigrationMode;
use Google\Generator\Utils\ProtoCatalog;
use Google\Generator\Utils\ProtoHelpers;
use Google\Generator\Utils\ServiceYamlConfig;
Expand All @@ -43,15 +44,18 @@ private static function ensureDecimal(string $s): string

public static function generateDescriptorConfig(ServiceDetails $serviceDetails, GapicYamlConfig $gapicYamlConfig): string
{
$perMethod = function ($method) use ($gapicYamlConfig, $serviceDetails) {
$preMigrationOnly = $serviceDetails->migrationMode == MigrationMode::PRE_MIGRATION_SURFACE_ONLY;
$perMethod = function ($method) use ($gapicYamlConfig, $serviceDetails, $preMigrationOnly) {
switch ($method->methodType) {
case MethodDetails::CUSTOM_OP:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::LONGRUNNING_CALL'),
// Include the responseType for Custom Operations because they define their own operation class.
'responseType' => $method->responseType->getFullName(true),
'longRunning' => static::customOperationDescriptor($serviceDetails, $method)
];
if (!$preMigrationOnly) {
// Include the responseType for Custom Operations because they define their own operation class.
$descriptor['responseType'] = $method->responseType->getFullName(true);
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::LONGRUNNING_CALL');
}
break;
case MethodDetails::LRO:
$methodGapicConfig = $gapicYamlConfig->configsByMethodName->get($method->name, null);
Expand All @@ -69,7 +73,6 @@ public static function generateDescriptorConfig(ServiceDetails $serviceDetails,
$totalPollTimeoutMillis = '300000';
}
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::LONGRUNNING_CALL'),
'longRunning' => AST::array([
'operationReturnType' => $method->lroResponseType->getFullname(),
'metadataReturnType' => $method->lroMetadataType->getFullname(),
Expand All @@ -79,11 +82,12 @@ public static function generateDescriptorConfig(ServiceDetails $serviceDetails,
'totalPollTimeoutMillis' => $totalPollTimeoutMillis,
])
];
if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::LONGRUNNING_CALL');
}
break;
case MethodDetails::PAGINATED:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::PAGINATED_CALL'),
'responseType' => $method->responseType->getFullName(true),
'pageStreaming' => AST::array([
'requestPageTokenGetMethod' => $method->requestPageTokenGetter->name,
'requestPageTokenSetMethod' => $method->requestPageTokenSetter->name,
Expand All @@ -93,43 +97,55 @@ public static function generateDescriptorConfig(ServiceDetails $serviceDetails,
'resourcesGetMethod' => $method->resourcesGetter->name,
])
];
if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::PAGINATED_CALL');
$descriptor['responseType'] = $method->responseType->getFullName(true);
}
break;
case MethodDetails::BIDI_STREAMING:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::BIDI_STREAMING_CALL'),
'responseType' => $method->responseType->getFullName(true),
'grpcStreaming' => AST::array([
'grpcStreamingType' => 'BidiStreaming',
])
];
if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::BIDI_STREAMING_CALL');
$descriptor['responseType'] = $method->responseType->getFullName(true);
}
break;
case MethodDetails::SERVER_STREAMING:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::SERVER_STREAMING_CALL'),
'responseType' => $method->responseType->getFullName(true),
'grpcStreaming' => AST::array([
'grpcStreamingType' => 'ServerStreaming',
])
];
if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::SERVER_STREAMING_CALL');
$descriptor['responseType'] = $method->responseType->getFullName(true);
}
break;
case MethodDetails::CLIENT_STREAMING:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::CLIENT_STREAMING_CALL'),
'responseType' => $method->responseType->getFullName(true),
'grpcStreaming' => AST::array([
'grpcStreamingType' => 'ClientStreaming',
])
];
if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::CLIENT_STREAMING_CALL');
$descriptor['responseType'] = $method->responseType->getFullName(true);
}
break;
default:
$descriptor = [
'callType' => AST::literal('\Google\ApiCore\Call::UNARY_CALL'),
'responseType' => $method->responseType->getFullName(true)
];
$descriptor = [];

if (!$preMigrationOnly) {
$descriptor['callType'] = AST::literal('\Google\ApiCore\Call::UNARY_CALL');
$descriptor['responseType'] = $method->responseType->getFullName(true);
}
break;
}

if ($method->headerParams) {
if ($method->headerParams && !$preMigrationOnly) {
$descriptor['headerParams'] = $method->headerParams;
}

Expand All @@ -146,7 +162,7 @@ public static function generateDescriptorConfig(ServiceDetails $serviceDetails,
->orderBy(fn ($x) => isset($x[1]['longRunning']) ? 0 : 1) // LRO come first
->toArray(fn ($x) => $x[0], fn ($x) => AST::array($x[1]));

if ($serviceDetails->hasResources) {
if ($serviceDetails->hasResources && !$preMigrationOnly) {
$serviceDescriptor['templateMap'] = $serviceDetails->resourceParts
->toArray(fn($x) => $x->getNameCamelCase(), fn($x) => $x->getPattern());
}
Expand Down
4 changes: 2 additions & 2 deletions src/Generation/SnippetGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private function generateImpl(): array

foreach ($this->serviceDetails->methods as $method) {
$regionTag = $this->generateRegionTag($method->name);
$snippetDetails = $this->serviceDetails->migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED ?
$snippetDetails = $this->serviceDetails->migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED || $this->serviceDetails->migrationMode == MigrationMode::PRE_MIGRATION_SURFACE_ONLY ?
new SnippetDetails($method, $this->serviceDetails) :
new SnippetDetailsV2($method, $this->serviceDetails);
$rpcMethodExample = $this->rpcMethodExample($snippetDetails);
Expand Down Expand Up @@ -378,7 +378,7 @@ private function buildSnippetFunctions(SnippetDetails $snippetDetails, array $tr
$shouldGenerateDocBlock = $docLineCount > 0
|| count($snippetDetails->phpDocParams) > 0
|| !$hasSampleParams;
$clientType = $this->serviceDetails->migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED ?
$clientType = $this->serviceDetails->migrationMode == MigrationMode::MIGRATION_MODE_UNSPECIFIED || $this->serviceDetails->migrationMode == MigrationMode::PRE_MIGRATION_SURFACE_ONLY ?
$this->serviceDetails->emptyClientType :
$this->serviceDetails->emptyClientV2Type;

Expand Down
4 changes: 3 additions & 1 deletion src/Utils/MigrationMode.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
class MigrationMode
{
public const MIGRATION_MODE_UNSPECIFIED = "MIGRATION_MODE_UNSPECIFIED";
public const PRE_MIGRATION_SURFACE_ONLY = "PRE_MIGRATION_SURFACE_ONLY";
public const NEW_SURFACE_ONLY = "NEW_SURFACE_ONLY";
public const MIGRATING = "MIGRATING";

Expand All @@ -33,9 +34,10 @@ public static function validateMode(string $mode): void
{
$invalid = $mode != self::MIGRATION_MODE_UNSPECIFIED
&& $mode != self::NEW_SURFACE_ONLY
&& $mode != self::PRE_MIGRATION_SURFACE_ONLY
&& $mode != self::MIGRATING;
if ($invalid) {
throw new \Exception("Invalid migration mode '{$mode}', allowed values are: 'MIGRATION_MODE_UNSPECIFIED', 'NEW_SURFACE_ONLY', 'MIGRATING'");
throw new \Exception("Invalid migration mode '{$mode}', allowed values are: 'MIGRATION_MODE_UNSPECIFIED', 'PRE_MIGRATION_SURFACE_ONLY', 'NEW_SURFACE_ONLY', 'MIGRATING'");
}
}
}
1 change: 1 addition & 0 deletions tests/Integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ php_gapic_library(
srcs = ["@com_google_googleapis//google/cloud/speech/v1:speech_proto_with_info"],
grpc_service_config = "@com_google_googleapis//google/cloud/speech/v1:speech_grpc_service_config.json",
service_yaml = "@com_google_googleapis//google/cloud/speech/v1:speech_v1.yaml",
migration_mode = "PRE_MIGRATION_SURFACE_ONLY",
deps = [
":speech_php_grpc",
":speech_php_proto",
Expand Down
Loading

0 comments on commit dc1a2a1

Please sign in to comment.