<?php
namespace Aws;

use Aws\Api\Parser\Exception\ParserException;
use Aws\Exception\AwsException;
use GuzzleHttp\Promise;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * Converts an HTTP handler into a Command HTTP handler.
 *
 * HTTP handlers have the following signature:
 *     function(RequestInterface $request, array $options) : PromiseInterface
 *
 * The promise returned form an HTTP handler must resolve to a PSR-7 response
 * object when fulfilled or an error array when rejected. The error array
 * can contain the following data:
 *
 * - exception: (required, Exception) Exception that was encountered.
 * - response: (ResponseInterface) PSR-7 response that was received (if a
 *   response) was received.
 * - connection_error: (bool) True if the error is the result of failing to
 *   connect.
 */
class WrappedHttpHandler
{
    private $httpHandler;
    private $parser;
    private $errorParser;
    private $exceptionClass;
    private $collectStats;

    /**
     * @param callable $httpHandler    Function that accepts a request and array
     *                                 of request options and returns a promise
     *                                 that fulfills with a response or rejects
     *                                 with an error array.
     * @param callable $parser         Function that accepts a response object
     *                                 and returns an AWS result object.
     * @param callable $errorParser    Function that parses a response object
     *                                 into AWS error data.
     * @param string   $exceptionClass Exception class to throw.
     * @param bool     $collectStats   Whether to collect HTTP transfer
     *                                 information.
     */
    public function __construct(
        callable $httpHandler,
        callable $parser,
        callable $errorParser,
        $exceptionClass = AwsException::class,
        $collectStats = false
    ) {
        $this->httpHandler = $httpHandler;
        $this->parser = $parser;
        $this->errorParser = $errorParser;
        $this->exceptionClass = $exceptionClass;
        $this->collectStats = $collectStats;
    }

    /**
     * Calls the simpler HTTP specific handler and wraps the returned promise
     * with AWS specific values (e.g., a result object or AWS exception).
     *
     * @param CommandInterface $command Command being executed.
     * @param RequestInterface $request Request to send.
     *
     * @return Promise\PromiseInterface
     */
    public function __invoke(
        CommandInterface $command,
        RequestInterface $request
    ) {
        $fn = $this->httpHandler;
        $options = $command['@http'] ?: [];
        $stats = [];
        if ($this->collectStats || !empty($options['collect_stats'])) {
            $options['http_stats_receiver'] = static function (
                array $transferStats
            ) use (&$stats) {
                $stats = $transferStats;
            };
        } elseif (isset($options['http_stats_receiver'])) {
            throw new \InvalidArgumentException('Providing a custom HTTP stats'
                . ' receiver to Aws\WrappedHttpHandler is not supported.');
        }

        return Promise\Create::promiseFor($fn($request, $options))
            ->then(
                function (
                    ResponseInterface $res
                ) use ($command, $request, &$stats) {
                    return $this->parseResponse($command, $request, $res, $stats);
                },
                function ($err) use ($request, $command, &$stats) {
                    if (is_array($err)) {
                        $err = $this->parseError(
                            $err,
                            $request,
                            $command,
                            $stats
                        );
                    }
                    return new Promise\RejectedPromise($err);
                }
            );
    }

    /**
     * @param CommandInterface  $command
     * @param RequestInterface  $request
     * @param ResponseInterface $response
     * @param array             $stats
     *
     * @return ResultInterface
     */
    private function parseResponse(
        CommandInterface $command,
        RequestInterface $request,
        ResponseInterface $response,
        array $stats
    ) {
        $parser = $this->parser;
        $status = $response->getStatusCode();
        $result = $status < 300
            ? $parser($command, $response)
            : new Result();

        $metadata = [
            'statusCode'    => $status,
            'effectiveUri'  => (string) $request->getUri(),
            'headers'       => [],
            'transferStats' => [],
        ];
        if (!empty($stats)) {
            $metadata['transferStats']['http'] = [$stats];
        }

        // Bring headers into the metadata array.
        foreach ($response->getHeaders() as $name => $values) {
            $metadata['headers'][strtolower($name)] = $values[0];
        }

        $result['@metadata'] = $metadata;

        return $result;
    }

    /**
     * Parses a rejection into an AWS error.
     *
     * @param array            $err     Rejection error array.
     * @param RequestInterface $request Request that was sent.
     * @param CommandInterface $command Command being sent.
     * @param array            $stats   Transfer statistics
     *
     * @return \Exception
     */
    private function parseError(
        array $err,
        RequestInterface $request,
        CommandInterface $command,
        array $stats
    ) {
        if (!isset($err['exception'])) {
            throw new \RuntimeException('The HTTP handler was rejected without an "exception" key value pair.');
        }

        $serviceError = "AWS HTTP error: " . $err['exception']->getMessage();

        if (!isset($err['response'])) {
            $parts = ['response' => null];
        } else {
            try {
                $parts = call_user_func(
                    $this->errorParser,
                    $err['response'],
                    $command
                );
                $serviceError .= " {$parts['code']} ({$parts['type']}): "
                    . "{$parts['message']} - " . $err['response']->getBody();
            } catch (ParserException $e) {
                $parts = [];
                $serviceError .= ' Unable to parse error information from '
                    . "response - {$e->getMessage()}";
            }

            $parts['response'] = $err['response'];
        }

        $parts['exception'] = $err['exception'];
        $parts['request'] = $request;
        $parts['connection_error'] = !empty($err['connection_error']);
        $parts['transfer_stats'] = $stats;

        return new $this->exceptionClass(
            sprintf(
                'Error executing "%s" on "%s"; %s',
                $command->getName(),
                $request->getUri(),
                $serviceError
            ),
            $command,
            $parts,
            $err['exception']
        );
    }
}


<?php
namespace Aws\AccessAnalyzer;

use Aws\AwsClient;

/**
 * This client is used to interact with the **Access Analyzer** service.
 * @method \Aws\Result applyArchiveRule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise applyArchiveRuleAsync(array $args = [])
 * @method \Aws\Result cancelPolicyGeneration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise cancelPolicyGenerationAsync(array $args = [])
 * @method \Aws\Result createAccessPreview(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createAccessPreviewAsync(array $args = [])
 * @method \Aws\Result createAnalyzer(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createAnalyzerAsync(array $args = [])
 * @method \Aws\Result createArchiveRule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createArchiveRuleAsync(array $args = [])
 * @method \Aws\Result deleteAnalyzer(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteAnalyzerAsync(array $args = [])
 * @method \Aws\Result deleteArchiveRule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteArchiveRuleAsync(array $args = [])
 * @method \Aws\Result getAccessPreview(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAccessPreviewAsync(array $args = [])
 * @method \Aws\Result getAnalyzedResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAnalyzedResourceAsync(array $args = [])
 * @method \Aws\Result getAnalyzer(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAnalyzerAsync(array $args = [])
 * @method \Aws\Result getArchiveRule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getArchiveRuleAsync(array $args = [])
 * @method \Aws\Result getFinding(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getFindingAsync(array $args = [])
 * @method \Aws\Result getGeneratedPolicy(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getGeneratedPolicyAsync(array $args = [])
 * @method \Aws\Result listAccessPreviewFindings(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listAccessPreviewFindingsAsync(array $args = [])
 * @method \Aws\Result listAccessPreviews(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listAccessPreviewsAsync(array $args = [])
 * @method \Aws\Result listAnalyzedResources(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listAnalyzedResourcesAsync(array $args = [])
 * @method \Aws\Result listAnalyzers(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listAnalyzersAsync(array $args = [])
 * @method \Aws\Result listArchiveRules(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listArchiveRulesAsync(array $args = [])
 * @method \Aws\Result listFindings(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listFindingsAsync(array $args = [])
 * @method \Aws\Result listPolicyGenerations(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listPolicyGenerationsAsync(array $args = [])
 * @method \Aws\Result listTagsForResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
 * @method \Aws\Result startPolicyGeneration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startPolicyGenerationAsync(array $args = [])
 * @method \Aws\Result startResourceScan(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startResourceScanAsync(array $args = [])
 * @method \Aws\Result tagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
 * @method \Aws\Result untagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
 * @method \Aws\Result updateArchiveRule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateArchiveRuleAsync(array $args = [])
 * @method \Aws\Result updateFindings(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateFindingsAsync(array $args = [])
 * @method \Aws\Result validatePolicy(array $args = [])
 * @method \GuzzleHttp\Promise\Promise validatePolicyAsync(array $args = [])
 */
class AccessAnalyzerClient extends AwsClient {}


<?php
namespace Aws\AccessAnalyzer\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **Access Analyzer** service.
 */
class AccessAnalyzerException extends AwsException {}


<?php
namespace Aws\Account;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AWS Account** service.
 * @method \Aws\Result deleteAlternateContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteAlternateContactAsync(array $args = [])
 * @method \Aws\Result disableRegion(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disableRegionAsync(array $args = [])
 * @method \Aws\Result enableRegion(array $args = [])
 * @method \GuzzleHttp\Promise\Promise enableRegionAsync(array $args = [])
 * @method \Aws\Result getAlternateContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAlternateContactAsync(array $args = [])
 * @method \Aws\Result getContactInformation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getContactInformationAsync(array $args = [])
 * @method \Aws\Result getRegionOptStatus(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getRegionOptStatusAsync(array $args = [])
 * @method \Aws\Result listRegions(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listRegionsAsync(array $args = [])
 * @method \Aws\Result putAlternateContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putAlternateContactAsync(array $args = [])
 * @method \Aws\Result putContactInformation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putContactInformationAsync(array $args = [])
 */
class AccountClient extends AwsClient {}


<?php
namespace Aws\Account\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AWS Account** service.
 */
class AccountException extends AwsException {}


<?php
namespace Aws\Acm;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AWS Certificate Manager** service.
 *
 * @method \Aws\Result addTagsToCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise addTagsToCertificateAsync(array $args = [])
 * @method \Aws\Result deleteCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteCertificateAsync(array $args = [])
 * @method \Aws\Result describeCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise describeCertificateAsync(array $args = [])
 * @method \Aws\Result exportCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise exportCertificateAsync(array $args = [])
 * @method \Aws\Result getAccountConfiguration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAccountConfigurationAsync(array $args = [])
 * @method \Aws\Result getCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getCertificateAsync(array $args = [])
 * @method \Aws\Result importCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise importCertificateAsync(array $args = [])
 * @method \Aws\Result listCertificates(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listCertificatesAsync(array $args = [])
 * @method \Aws\Result listTagsForCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listTagsForCertificateAsync(array $args = [])
 * @method \Aws\Result putAccountConfiguration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putAccountConfigurationAsync(array $args = [])
 * @method \Aws\Result removeTagsFromCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise removeTagsFromCertificateAsync(array $args = [])
 * @method \Aws\Result renewCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise renewCertificateAsync(array $args = [])
 * @method \Aws\Result requestCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise requestCertificateAsync(array $args = [])
 * @method \Aws\Result resendValidationEmail(array $args = [])
 * @method \GuzzleHttp\Promise\Promise resendValidationEmailAsync(array $args = [])
 * @method \Aws\Result updateCertificateOptions(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateCertificateOptionsAsync(array $args = [])
 */
class AcmClient extends AwsClient {}


<?php
namespace Aws\Acm\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AWS Certificate Manager** service.
 */
class AcmException extends AwsException {}


<?php
namespace Aws\ACMPCA;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AWS Certificate Manager Private Certificate Authority** service.
 * @method \Aws\Result createCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result createCertificateAuthorityAuditReport(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createCertificateAuthorityAuditReportAsync(array $args = [])
 * @method \Aws\Result createPermission(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createPermissionAsync(array $args = [])
 * @method \Aws\Result deleteCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result deletePermission(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deletePermissionAsync(array $args = [])
 * @method \Aws\Result deletePolicy(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deletePolicyAsync(array $args = [])
 * @method \Aws\Result describeCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise describeCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result describeCertificateAuthorityAuditReport(array $args = [])
 * @method \GuzzleHttp\Promise\Promise describeCertificateAuthorityAuditReportAsync(array $args = [])
 * @method \Aws\Result getCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getCertificateAsync(array $args = [])
 * @method \Aws\Result getCertificateAuthorityCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getCertificateAuthorityCertificateAsync(array $args = [])
 * @method \Aws\Result getCertificateAuthorityCsr(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getCertificateAuthorityCsrAsync(array $args = [])
 * @method \Aws\Result getPolicy(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getPolicyAsync(array $args = [])
 * @method \Aws\Result importCertificateAuthorityCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise importCertificateAuthorityCertificateAsync(array $args = [])
 * @method \Aws\Result issueCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise issueCertificateAsync(array $args = [])
 * @method \Aws\Result listCertificateAuthorities(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listCertificateAuthoritiesAsync(array $args = [])
 * @method \Aws\Result listPermissions(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listPermissionsAsync(array $args = [])
 * @method \Aws\Result listTags(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listTagsAsync(array $args = [])
 * @method \Aws\Result putPolicy(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putPolicyAsync(array $args = [])
 * @method \Aws\Result restoreCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise restoreCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result revokeCertificate(array $args = [])
 * @method \GuzzleHttp\Promise\Promise revokeCertificateAsync(array $args = [])
 * @method \Aws\Result tagCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise tagCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result untagCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise untagCertificateAuthorityAsync(array $args = [])
 * @method \Aws\Result updateCertificateAuthority(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateCertificateAuthorityAsync(array $args = [])
 */
class ACMPCAClient extends AwsClient {}


<?php
namespace Aws\ACMPCA\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AWS Certificate Manager Private Certificate Authority** service.
 */
class ACMPCAException extends AwsException {}


<?php
namespace Aws\AlexaForBusiness;

use Aws\AwsClient;

/**
 * This client is used to interact with the **Alexa For Business** service.
 * @method \Aws\Result approveSkill(array $args = [])
 * @method \GuzzleHttp\Promise\Promise approveSkillAsync(array $args = [])
 * @method \Aws\Result associateContactWithAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateContactWithAddressBookAsync(array $args = [])
 * @method \Aws\Result associateDeviceWithNetworkProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateDeviceWithNetworkProfileAsync(array $args = [])
 * @method \Aws\Result associateDeviceWithRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateDeviceWithRoomAsync(array $args = [])
 * @method \Aws\Result associateSkillGroupWithRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateSkillGroupWithRoomAsync(array $args = [])
 * @method \Aws\Result associateSkillWithSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateSkillWithSkillGroupAsync(array $args = [])
 * @method \Aws\Result associateSkillWithUsers(array $args = [])
 * @method \GuzzleHttp\Promise\Promise associateSkillWithUsersAsync(array $args = [])
 * @method \Aws\Result createAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createAddressBookAsync(array $args = [])
 * @method \Aws\Result createBusinessReportSchedule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBusinessReportScheduleAsync(array $args = [])
 * @method \Aws\Result createConferenceProvider(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createConferenceProviderAsync(array $args = [])
 * @method \Aws\Result createContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createContactAsync(array $args = [])
 * @method \Aws\Result createGatewayGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createGatewayGroupAsync(array $args = [])
 * @method \Aws\Result createNetworkProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createNetworkProfileAsync(array $args = [])
 * @method \Aws\Result createProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createProfileAsync(array $args = [])
 * @method \Aws\Result createRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createRoomAsync(array $args = [])
 * @method \Aws\Result createSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createSkillGroupAsync(array $args = [])
 * @method \Aws\Result createUser(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createUserAsync(array $args = [])
 * @method \Aws\Result deleteAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteAddressBookAsync(array $args = [])
 * @method \Aws\Result deleteBusinessReportSchedule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBusinessReportScheduleAsync(array $args = [])
 * @method \Aws\Result deleteConferenceProvider(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteConferenceProviderAsync(array $args = [])
 * @method \Aws\Result deleteContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteContactAsync(array $args = [])
 * @method \Aws\Result deleteDevice(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteDeviceAsync(array $args = [])
 * @method \Aws\Result deleteDeviceUsageData(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteDeviceUsageDataAsync(array $args = [])
 * @method \Aws\Result deleteGatewayGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteGatewayGroupAsync(array $args = [])
 * @method \Aws\Result deleteNetworkProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteNetworkProfileAsync(array $args = [])
 * @method \Aws\Result deleteProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteProfileAsync(array $args = [])
 * @method \Aws\Result deleteRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteRoomAsync(array $args = [])
 * @method \Aws\Result deleteRoomSkillParameter(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteRoomSkillParameterAsync(array $args = [])
 * @method \Aws\Result deleteSkillAuthorization(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteSkillAuthorizationAsync(array $args = [])
 * @method \Aws\Result deleteSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteSkillGroupAsync(array $args = [])
 * @method \Aws\Result deleteUser(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteUserAsync(array $args = [])
 * @method \Aws\Result disassociateContactFromAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disassociateContactFromAddressBookAsync(array $args = [])
 * @method \Aws\Result disassociateDeviceFromRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disassociateDeviceFromRoomAsync(array $args = [])
 * @method \Aws\Result disassociateSkillFromSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disassociateSkillFromSkillGroupAsync(array $args = [])
 * @method \Aws\Result disassociateSkillFromUsers(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disassociateSkillFromUsersAsync(array $args = [])
 * @method \Aws\Result disassociateSkillGroupFromRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise disassociateSkillGroupFromRoomAsync(array $args = [])
 * @method \Aws\Result forgetSmartHomeAppliances(array $args = [])
 * @method \GuzzleHttp\Promise\Promise forgetSmartHomeAppliancesAsync(array $args = [])
 * @method \Aws\Result getAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAddressBookAsync(array $args = [])
 * @method \Aws\Result getConferencePreference(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getConferencePreferenceAsync(array $args = [])
 * @method \Aws\Result getConferenceProvider(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getConferenceProviderAsync(array $args = [])
 * @method \Aws\Result getContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getContactAsync(array $args = [])
 * @method \Aws\Result getDevice(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getDeviceAsync(array $args = [])
 * @method \Aws\Result getGateway(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getGatewayAsync(array $args = [])
 * @method \Aws\Result getGatewayGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getGatewayGroupAsync(array $args = [])
 * @method \Aws\Result getInvitationConfiguration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getInvitationConfigurationAsync(array $args = [])
 * @method \Aws\Result getNetworkProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getNetworkProfileAsync(array $args = [])
 * @method \Aws\Result getProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getProfileAsync(array $args = [])
 * @method \Aws\Result getRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getRoomAsync(array $args = [])
 * @method \Aws\Result getRoomSkillParameter(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getRoomSkillParameterAsync(array $args = [])
 * @method \Aws\Result getSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getSkillGroupAsync(array $args = [])
 * @method \Aws\Result listBusinessReportSchedules(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listBusinessReportSchedulesAsync(array $args = [])
 * @method \Aws\Result listConferenceProviders(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listConferenceProvidersAsync(array $args = [])
 * @method \Aws\Result listDeviceEvents(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listDeviceEventsAsync(array $args = [])
 * @method \Aws\Result listGatewayGroups(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listGatewayGroupsAsync(array $args = [])
 * @method \Aws\Result listGateways(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listGatewaysAsync(array $args = [])
 * @method \Aws\Result listSkills(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listSkillsAsync(array $args = [])
 * @method \Aws\Result listSkillsStoreCategories(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listSkillsStoreCategoriesAsync(array $args = [])
 * @method \Aws\Result listSkillsStoreSkillsByCategory(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listSkillsStoreSkillsByCategoryAsync(array $args = [])
 * @method \Aws\Result listSmartHomeAppliances(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listSmartHomeAppliancesAsync(array $args = [])
 * @method \Aws\Result listTags(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listTagsAsync(array $args = [])
 * @method \Aws\Result putConferencePreference(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putConferencePreferenceAsync(array $args = [])
 * @method \Aws\Result putInvitationConfiguration(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putInvitationConfigurationAsync(array $args = [])
 * @method \Aws\Result putRoomSkillParameter(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putRoomSkillParameterAsync(array $args = [])
 * @method \Aws\Result putSkillAuthorization(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putSkillAuthorizationAsync(array $args = [])
 * @method \Aws\Result registerAVSDevice(array $args = [])
 * @method \GuzzleHttp\Promise\Promise registerAVSDeviceAsync(array $args = [])
 * @method \Aws\Result rejectSkill(array $args = [])
 * @method \GuzzleHttp\Promise\Promise rejectSkillAsync(array $args = [])
 * @method \Aws\Result resolveRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise resolveRoomAsync(array $args = [])
 * @method \Aws\Result revokeInvitation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise revokeInvitationAsync(array $args = [])
 * @method \Aws\Result searchAddressBooks(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchAddressBooksAsync(array $args = [])
 * @method \Aws\Result searchContacts(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchContactsAsync(array $args = [])
 * @method \Aws\Result searchDevices(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchDevicesAsync(array $args = [])
 * @method \Aws\Result searchNetworkProfiles(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchNetworkProfilesAsync(array $args = [])
 * @method \Aws\Result searchProfiles(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchProfilesAsync(array $args = [])
 * @method \Aws\Result searchRooms(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchRoomsAsync(array $args = [])
 * @method \Aws\Result searchSkillGroups(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchSkillGroupsAsync(array $args = [])
 * @method \Aws\Result searchUsers(array $args = [])
 * @method \GuzzleHttp\Promise\Promise searchUsersAsync(array $args = [])
 * @method \Aws\Result sendAnnouncement(array $args = [])
 * @method \GuzzleHttp\Promise\Promise sendAnnouncementAsync(array $args = [])
 * @method \Aws\Result sendInvitation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise sendInvitationAsync(array $args = [])
 * @method \Aws\Result startDeviceSync(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startDeviceSyncAsync(array $args = [])
 * @method \Aws\Result startSmartHomeApplianceDiscovery(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startSmartHomeApplianceDiscoveryAsync(array $args = [])
 * @method \Aws\Result tagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
 * @method \Aws\Result untagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
 * @method \Aws\Result updateAddressBook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateAddressBookAsync(array $args = [])
 * @method \Aws\Result updateBusinessReportSchedule(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBusinessReportScheduleAsync(array $args = [])
 * @method \Aws\Result updateConferenceProvider(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateConferenceProviderAsync(array $args = [])
 * @method \Aws\Result updateContact(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateContactAsync(array $args = [])
 * @method \Aws\Result updateDevice(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateDeviceAsync(array $args = [])
 * @method \Aws\Result updateGateway(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateGatewayAsync(array $args = [])
 * @method \Aws\Result updateGatewayGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateGatewayGroupAsync(array $args = [])
 * @method \Aws\Result updateNetworkProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateNetworkProfileAsync(array $args = [])
 * @method \Aws\Result updateProfile(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateProfileAsync(array $args = [])
 * @method \Aws\Result updateRoom(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateRoomAsync(array $args = [])
 * @method \Aws\Result updateSkillGroup(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateSkillGroupAsync(array $args = [])
 */
class AlexaForBusinessClient extends AwsClient {}


<?php
namespace Aws\AlexaForBusiness\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **Alexa For Business** service.
 */
class AlexaForBusinessException extends AwsException {}


<?php
namespace Aws\Amplify;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AWS Amplify** service.
 * @method \Aws\Result createApp(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createAppAsync(array $args = [])
 * @method \Aws\Result createBackendEnvironment(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendEnvironmentAsync(array $args = [])
 * @method \Aws\Result createBranch(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBranchAsync(array $args = [])
 * @method \Aws\Result createDeployment(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createDeploymentAsync(array $args = [])
 * @method \Aws\Result createDomainAssociation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createDomainAssociationAsync(array $args = [])
 * @method \Aws\Result createWebhook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createWebhookAsync(array $args = [])
 * @method \Aws\Result deleteApp(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteAppAsync(array $args = [])
 * @method \Aws\Result deleteBackendEnvironment(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBackendEnvironmentAsync(array $args = [])
 * @method \Aws\Result deleteBranch(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBranchAsync(array $args = [])
 * @method \Aws\Result deleteDomainAssociation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteDomainAssociationAsync(array $args = [])
 * @method \Aws\Result deleteJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteJobAsync(array $args = [])
 * @method \Aws\Result deleteWebhook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteWebhookAsync(array $args = [])
 * @method \Aws\Result generateAccessLogs(array $args = [])
 * @method \GuzzleHttp\Promise\Promise generateAccessLogsAsync(array $args = [])
 * @method \Aws\Result getApp(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getAppAsync(array $args = [])
 * @method \Aws\Result getArtifactUrl(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getArtifactUrlAsync(array $args = [])
 * @method \Aws\Result getBackendEnvironment(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendEnvironmentAsync(array $args = [])
 * @method \Aws\Result getBranch(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBranchAsync(array $args = [])
 * @method \Aws\Result getDomainAssociation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getDomainAssociationAsync(array $args = [])
 * @method \Aws\Result getJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getJobAsync(array $args = [])
 * @method \Aws\Result getWebhook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getWebhookAsync(array $args = [])
 * @method \Aws\Result listApps(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listAppsAsync(array $args = [])
 * @method \Aws\Result listArtifacts(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listArtifactsAsync(array $args = [])
 * @method \Aws\Result listBackendEnvironments(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listBackendEnvironmentsAsync(array $args = [])
 * @method \Aws\Result listBranches(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listBranchesAsync(array $args = [])
 * @method \Aws\Result listDomainAssociations(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listDomainAssociationsAsync(array $args = [])
 * @method \Aws\Result listJobs(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listJobsAsync(array $args = [])
 * @method \Aws\Result listTagsForResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
 * @method \Aws\Result listWebhooks(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listWebhooksAsync(array $args = [])
 * @method \Aws\Result startDeployment(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startDeploymentAsync(array $args = [])
 * @method \Aws\Result startJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startJobAsync(array $args = [])
 * @method \Aws\Result stopJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise stopJobAsync(array $args = [])
 * @method \Aws\Result tagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
 * @method \Aws\Result untagResource(array $args = [])
 * @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
 * @method \Aws\Result updateApp(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateAppAsync(array $args = [])
 * @method \Aws\Result updateBranch(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBranchAsync(array $args = [])
 * @method \Aws\Result updateDomainAssociation(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateDomainAssociationAsync(array $args = [])
 * @method \Aws\Result updateWebhook(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateWebhookAsync(array $args = [])
 */
class AmplifyClient extends AwsClient {}


<?php
namespace Aws\Amplify\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AWS Amplify** service.
 */
class AmplifyException extends AwsException {}


<?php
namespace Aws\AmplifyBackend;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AmplifyBackend** service.
 * @method \Aws\Result cloneBackend(array $args = [])
 * @method \GuzzleHttp\Promise\Promise cloneBackendAsync(array $args = [])
 * @method \Aws\Result createBackend(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendAsync(array $args = [])
 * @method \Aws\Result createBackendAPI(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendAPIAsync(array $args = [])
 * @method \Aws\Result createBackendAuth(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendAuthAsync(array $args = [])
 * @method \Aws\Result createBackendConfig(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendConfigAsync(array $args = [])
 * @method \Aws\Result createBackendStorage(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createBackendStorageAsync(array $args = [])
 * @method \Aws\Result createToken(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createTokenAsync(array $args = [])
 * @method \Aws\Result deleteBackend(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBackendAsync(array $args = [])
 * @method \Aws\Result deleteBackendAPI(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBackendAPIAsync(array $args = [])
 * @method \Aws\Result deleteBackendAuth(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBackendAuthAsync(array $args = [])
 * @method \Aws\Result deleteBackendStorage(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteBackendStorageAsync(array $args = [])
 * @method \Aws\Result deleteToken(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteTokenAsync(array $args = [])
 * @method \Aws\Result generateBackendAPIModels(array $args = [])
 * @method \GuzzleHttp\Promise\Promise generateBackendAPIModelsAsync(array $args = [])
 * @method \Aws\Result getBackend(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendAsync(array $args = [])
 * @method \Aws\Result getBackendAPI(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendAPIAsync(array $args = [])
 * @method \Aws\Result getBackendAPIModels(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendAPIModelsAsync(array $args = [])
 * @method \Aws\Result getBackendAuth(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendAuthAsync(array $args = [])
 * @method \Aws\Result getBackendJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendJobAsync(array $args = [])
 * @method \Aws\Result getBackendStorage(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getBackendStorageAsync(array $args = [])
 * @method \Aws\Result getToken(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getTokenAsync(array $args = [])
 * @method \Aws\Result importBackendAuth(array $args = [])
 * @method \GuzzleHttp\Promise\Promise importBackendAuthAsync(array $args = [])
 * @method \Aws\Result importBackendStorage(array $args = [])
 * @method \GuzzleHttp\Promise\Promise importBackendStorageAsync(array $args = [])
 * @method \Aws\Result listBackendJobs(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listBackendJobsAsync(array $args = [])
 * @method \Aws\Result listS3Buckets(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listS3BucketsAsync(array $args = [])
 * @method \Aws\Result removeAllBackends(array $args = [])
 * @method \GuzzleHttp\Promise\Promise removeAllBackendsAsync(array $args = [])
 * @method \Aws\Result removeBackendConfig(array $args = [])
 * @method \GuzzleHttp\Promise\Promise removeBackendConfigAsync(array $args = [])
 * @method \Aws\Result updateBackendAPI(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBackendAPIAsync(array $args = [])
 * @method \Aws\Result updateBackendAuth(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBackendAuthAsync(array $args = [])
 * @method \Aws\Result updateBackendConfig(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBackendConfigAsync(array $args = [])
 * @method \Aws\Result updateBackendJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBackendJobAsync(array $args = [])
 * @method \Aws\Result updateBackendStorage(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateBackendStorageAsync(array $args = [])
 */
class AmplifyBackendClient extends AwsClient {}


<?php
namespace Aws\AmplifyBackend\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AmplifyBackend** service.
 */
class AmplifyBackendException extends AwsException {}


<?php
namespace Aws\AmplifyUIBuilder;

use Aws\AwsClient;

/**
 * This client is used to interact with the **AWS Amplify UI Builder** service.
 * @method \Aws\Result createComponent(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createComponentAsync(array $args = [])
 * @method \Aws\Result createForm(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createFormAsync(array $args = [])
 * @method \Aws\Result createTheme(array $args = [])
 * @method \GuzzleHttp\Promise\Promise createThemeAsync(array $args = [])
 * @method \Aws\Result deleteComponent(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteComponentAsync(array $args = [])
 * @method \Aws\Result deleteForm(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteFormAsync(array $args = [])
 * @method \Aws\Result deleteTheme(array $args = [])
 * @method \GuzzleHttp\Promise\Promise deleteThemeAsync(array $args = [])
 * @method \Aws\Result exchangeCodeForToken(array $args = [])
 * @method \GuzzleHttp\Promise\Promise exchangeCodeForTokenAsync(array $args = [])
 * @method \Aws\Result exportComponents(array $args = [])
 * @method \GuzzleHttp\Promise\Promise exportComponentsAsync(array $args = [])
 * @method \Aws\Result exportForms(array $args = [])
 * @method \GuzzleHttp\Promise\Promise exportFormsAsync(array $args = [])
 * @method \Aws\Result exportThemes(array $args = [])
 * @method \GuzzleHttp\Promise\Promise exportThemesAsync(array $args = [])
 * @method \Aws\Result getCodegenJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getCodegenJobAsync(array $args = [])
 * @method \Aws\Result getComponent(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getComponentAsync(array $args = [])
 * @method \Aws\Result getForm(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getFormAsync(array $args = [])
 * @method \Aws\Result getMetadata(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getMetadataAsync(array $args = [])
 * @method \Aws\Result getTheme(array $args = [])
 * @method \GuzzleHttp\Promise\Promise getThemeAsync(array $args = [])
 * @method \Aws\Result listCodegenJobs(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listCodegenJobsAsync(array $args = [])
 * @method \Aws\Result listComponents(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listComponentsAsync(array $args = [])
 * @method \Aws\Result listForms(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listFormsAsync(array $args = [])
 * @method \Aws\Result listThemes(array $args = [])
 * @method \GuzzleHttp\Promise\Promise listThemesAsync(array $args = [])
 * @method \Aws\Result putMetadataFlag(array $args = [])
 * @method \GuzzleHttp\Promise\Promise putMetadataFlagAsync(array $args = [])
 * @method \Aws\Result refreshToken(array $args = [])
 * @method \GuzzleHttp\Promise\Promise refreshTokenAsync(array $args = [])
 * @method \Aws\Result startCodegenJob(array $args = [])
 * @method \GuzzleHttp\Promise\Promise startCodegenJobAsync(array $args = [])
 * @method \Aws\Result updateComponent(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateComponentAsync(array $args = [])
 * @method \Aws\Result updateForm(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateFormAsync(array $args = [])
 * @method \Aws\Result updateTheme(array $args = [])
 * @method \GuzzleHttp\Promise\Promise updateThemeAsync(array $args = [])
 */
class AmplifyUIBuilderClient extends AwsClient {}


<?php
namespace Aws\AmplifyUIBuilder\Exception;

use Aws\Exception\AwsException;

/**
 * Represents an error interacting with the **AWS Amplify UI Builder** service.
 */
class AmplifyUIBuilderException extends AwsException {}


<?php
namespace Aws\Api;

/**
 * Base class that is used by most API shapes
 */
abstract class AbstractModel implements \ArrayAccess
{
    /** @var array */
    protected $definition;

    /** @var ShapeMap */
    protected $shapeMap;

    /** @var array */
    protected $contextParam;

    /**
     * @param array    $definition Service description
     * @param ShapeMap $shapeMap   Shapemap used for creating shapes
     */
    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $this->definition = $definition;
        $this->shapeMap = $shapeMap;
        if (isset($definition['contextParam'])) {
            $this->contextParam = $definition['contextParam'];
        }
    }

    public function toArray()
    {
        return $this->definition;
    }

    /**
     * @return mixed|null
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return isset($this->definition[$offset])
            ? $this->definition[$offset] : null;
    }

    /**
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetSet($offset, $value)
    {
        $this->definition[$offset] = $value;
    }

    /**
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function offsetExists($offset)
    {
        return isset($this->definition[$offset]);
    }

    /**
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetUnset($offset)
    {
        unset($this->definition[$offset]);
    }

    protected function shapeAt($key)
    {
        if (!isset($this->definition[$key])) {
            throw new \InvalidArgumentException('Expected shape definition at '
                . $key);
        }

        return $this->shapeFor($this->definition[$key]);
    }

    protected function shapeFor(array $definition)
    {
        return isset($definition['shape'])
            ? $this->shapeMap->resolve($definition)
            : Shape::create($definition, $this->shapeMap);
    }
}


<?php
namespace Aws\Api;

use Aws\Exception\UnresolvedApiException;

/**
 * API providers.
 *
 * An API provider is a function that accepts a type, service, and version and
 * returns an array of API data on success or NULL if no API data can be created
 * for the provided arguments.
 *
 * You can wrap your calls to an API provider with the
 * {@see ApiProvider::resolve} method to ensure that API data is created. If the
 * API data is not created, then the resolve() method will throw a
 * {@see Aws\Exception\UnresolvedApiException}.
 *
 *     use Aws\Api\ApiProvider;
 *     $provider = ApiProvider::defaultProvider();
 *     // Returns an array or NULL.
 *     $data = $provider('api', 's3', '2006-03-01');
 *     // Returns an array or throws.
 *     $data = ApiProvider::resolve($provider, 'api', 'elasticfood', '2020-01-01');
 *
 * You can compose multiple providers into a single provider using
 * {@see Aws\or_chain}. This method accepts providers as arguments and
 * returns a new function that will invoke each provider until a non-null value
 * is returned.
 *
 *     $a = ApiProvider::filesystem(sys_get_temp_dir() . '/aws-beta-models');
 *     $b = ApiProvider::manifest();
 *
 *     $c = \Aws\or_chain($a, $b);
 *     $data = $c('api', 'betaservice', '2015-08-08'); // $a handles this.
 *     $data = $c('api', 's3', '2006-03-01');          // $b handles this.
 *     $data = $c('api', 'invalid', '2014-12-15');     // Neither handles this.
 */
class ApiProvider
{
    /** @var array A map of public API type names to their file suffix. */
    private static $typeMap = [
        'api'       => 'api-2',
        'paginator' => 'paginators-1',
        'waiter'    => 'waiters-2',
        'docs'      => 'docs-2',
    ];

    /** @var array API manifest */
    private $manifest;

    /** @var string The directory containing service models. */
    private $modelsDir;

    /**
     * Resolves an API provider and ensures a non-null return value.
     *
     * @param callable $provider Provider function to invoke.
     * @param string   $type     Type of data ('api', 'waiter', 'paginator').
     * @param string   $service  Service name.
     * @param string   $version  API version.
     *
     * @return array
     * @throws UnresolvedApiException
     */
    public static function resolve(callable $provider, $type, $service, $version)
    {
        // Execute the provider and return the result, if there is one.
        $result = $provider($type, $service, $version);
        if (is_array($result)) {
            if (!isset($result['metadata']['serviceIdentifier'])) {
                $result['metadata']['serviceIdentifier'] = $service;
            }
            return $result;
        }

        // Throw an exception with a message depending on the inputs.
        if (!isset(self::$typeMap[$type])) {
            $msg = "The type must be one of: " . implode(', ', self::$typeMap);
        } elseif ($service) {
            $msg = "The {$service} service does not have version: {$version}.";
        } else {
            $msg = "You must specify a service name to retrieve its API data.";
        }

        throw new UnresolvedApiException($msg);
    }

    /**
     * Default SDK API provider.
     *
     * This provider loads pre-built manifest data from the `data` directory.
     *
     * @return self
     */
    public static function defaultProvider()
    {
        return new self(__DIR__ . '/../data', \Aws\manifest());
    }

    /**
     * Loads API data after resolving the version to the latest, compatible,
     * available version based on the provided manifest data.
     *
     * Manifest data is essentially an associative array of service names to
     * associative arrays of API version aliases.
     *
     * [
     *   ...
     *   'ec2' => [
     *     'latest'     => '2014-10-01',
     *     '2014-10-01' => '2014-10-01',
     *     '2014-09-01' => '2014-10-01',
     *     '2014-06-15' => '2014-10-01',
     *     ...
     *   ],
     *   'ecs' => [...],
     *   'elasticache' => [...],
     *   ...
     * ]
     *
     * @param string $dir      Directory containing service models.
     * @param array  $manifest The API version manifest data.
     *
     * @return self
     */
    public static function manifest($dir, array $manifest)
    {
        return new self($dir, $manifest);
    }

    /**
     * Loads API data from the specified directory.
     *
     * If "latest" is specified as the version, this provider must glob the
     * directory to find which is the latest available version.
     *
     * @param string $dir Directory containing service models.
     *
     * @return self
     * @throws \InvalidArgumentException if the provided `$dir` is invalid.
     */
    public static function filesystem($dir)
    {
        return new self($dir);
    }

    /**
     * Retrieves a list of valid versions for the specified service.
     *
     * @param string $service Service name
     *
     * @return array
     */
    public function getVersions($service)
    {
        if (!isset($this->manifest)) {
            $this->buildVersionsList($service);
        }

        if (!isset($this->manifest[$service]['versions'])) {
            return [];
        }

        return array_values(array_unique($this->manifest[$service]['versions']));
    }

    /**
     * Execute the provider.
     *
     * @param string $type    Type of data ('api', 'waiter', 'paginator').
     * @param string $service Service name.
     * @param string $version API version.
     *
     * @return array|null
     */
    public function __invoke($type, $service, $version)
    {
        // Resolve the type or return null.
        if (isset(self::$typeMap[$type])) {
            $type = self::$typeMap[$type];
        } else {
            return null;
        }

        // Resolve the version or return null.
        if (!isset($this->manifest)) {
            $this->buildVersionsList($service);
        }

        if (!isset($this->manifest[$service]['versions'][$version])) {
            return null;
        }

        $version = $this->manifest[$service]['versions'][$version];
        $path = "{$this->modelsDir}/{$service}/{$version}/{$type}.json";

        try {
            return \Aws\load_compiled_json($path);
        } catch (\InvalidArgumentException $e) {
            return null;
        }
    }

    /**
     * @param string $modelsDir Directory containing service models.
     * @param array  $manifest  The API version manifest data.
     */
    private function __construct($modelsDir, array $manifest = null)
    {
        $this->manifest = $manifest;
        $this->modelsDir = rtrim($modelsDir, '/');
        if (!is_dir($this->modelsDir)) {
            throw new \InvalidArgumentException(
                "The specified models directory, {$modelsDir}, was not found."
            );
        }
    }

    /**
     * Build the versions list for the specified service by globbing the dir.
     */
    private function buildVersionsList($service)
    {
        $dir = "{$this->modelsDir}/{$service}/";

        if (!is_dir($dir)) {
            return;
        }

        // Get versions, remove . and .., and sort in descending order.
        $results = array_diff(scandir($dir, SCANDIR_SORT_DESCENDING), ['..', '.']);

        if (!$results) {
            $this->manifest[$service] = ['versions' => []];
        } else {
            $this->manifest[$service] = [
                'versions' => [
                    'latest' => $results[0]
                ]
            ];
            $this->manifest[$service]['versions'] += array_combine($results, $results);
        }
    }
}


<?php

namespace Aws\Api;

use Aws\Api\Parser\Exception\ParserException;
use DateTime;
use DateTimeZone;
use Exception;

/**
 * DateTime overrides that make DateTime work more seamlessly as a string,
 * with JSON documents, and with JMESPath.
 */
class DateTimeResult extends \DateTime implements \JsonSerializable
{
    /**
     * Create a new DateTimeResult from a unix timestamp.
     * The Unix epoch (or Unix time or POSIX time or Unix
     * timestamp) is the number of seconds that have elapsed since
     * January 1, 1970 (midnight UTC/GMT).
     *
     * @return DateTimeResult
     * @throws Exception
     */
    public static function fromEpoch($unixTimestamp)
    {
        if (!is_numeric($unixTimestamp)) {
            throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromEpoch');
        }

        // PHP 5.5 does not support sub-second precision
        if (\PHP_VERSION_ID < 56000) {
            return new self(gmdate('c', $unixTimestamp));
        }

        $decimalSeparator = isset(localeconv()['decimal_point']) ? localeconv()['decimal_point'] : ".";
        $formatString = "U" . $decimalSeparator . "u";
        $dateTime = DateTime::createFromFormat(
            $formatString,
            sprintf('%0.6f', $unixTimestamp),
            new DateTimeZone('UTC')
        );

        if (false === $dateTime) {
            throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromEpoch');
        }

        return new self(
            $dateTime->format('Y-m-d H:i:s.u'),
            new DateTimeZone('UTC')
        );
    }

    /**
     * @return DateTimeResult
     */
    public static function fromISO8601($iso8601Timestamp)
    {
        if (is_numeric($iso8601Timestamp) || !is_string($iso8601Timestamp)) {
            throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromISO8601');
        }

        return new DateTimeResult($iso8601Timestamp);
    }

    /**
     * Create a new DateTimeResult from an unknown timestamp.
     *
     * @return DateTimeResult
     * @throws Exception
     */
    public static function fromTimestamp($timestamp, $expectedFormat = null)
    {
        if (empty($timestamp)) {
            return self::fromEpoch(0);
        }

        if (!(is_string($timestamp) || is_numeric($timestamp))) {
            throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
        }

        try {
            if ($expectedFormat == 'iso8601') {
                try {
                    return self::fromISO8601($timestamp);
                } catch (Exception $exception) {
                    return self::fromEpoch($timestamp);
                }
            } else if ($expectedFormat == 'unixTimestamp') {
                try {
                    return self::fromEpoch($timestamp);
                } catch (Exception $exception) {
                    return self::fromISO8601($timestamp);
                }
            } else if (\Aws\is_valid_epoch($timestamp)) {
                return self::fromEpoch($timestamp);
            }
            return self::fromISO8601($timestamp);
        } catch (Exception $exception) {
            throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
        }
    }

    /**
     * Serialize the DateTimeResult as an ISO 8601 date string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->format('c');
    }

    /**
     * Serialize the date as an ISO 8601 date when serializing as JSON.
     *
     * @return string
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return (string) $this;
    }
}


<?php
namespace Aws\Api;

/**
 * Encapsulates the documentation strings for a given service-version and
 * provides methods for extracting the desired parts related to a service,
 * operation, error, or shape (i.e., parameter).
 */
class DocModel
{
    /** @var array */
    private $docs;

    /**
     * @param array $docs
     *
     * @throws \RuntimeException
     */
    public function __construct(array $docs)
    {
        if (!extension_loaded('tidy')) {
            throw new \RuntimeException('The "tidy" PHP extension is required.');
        }

        $this->docs = $docs;
    }

    /**
     * Convert the doc model to an array.
     *
     * @return array
     */
    public function toArray()
    {
        return $this->docs;
    }

    /**
     * Retrieves documentation about the service.
     *
     * @return null|string
     */
    public function getServiceDocs()
    {
        return isset($this->docs['service']) ? $this->docs['service'] : null;
    }

    /**
     * Retrieves documentation about an operation.
     *
     * @param string $operation Name of the operation
     *
     * @return null|string
     */
    public function getOperationDocs($operation)
    {
        return isset($this->docs['operations'][$operation])
            ? $this->docs['operations'][$operation]
            : null;
    }

    /**
     * Retrieves documentation about an error.
     *
     * @param string $error Name of the error
     *
     * @return null|string
     */
    public function getErrorDocs($error)
    {
        return isset($this->docs['shapes'][$error]['base'])
            ? $this->docs['shapes'][$error]['base']
            : null;
    }

    /**
     * Retrieves documentation about a shape, specific to the context.
     *
     * @param string $shapeName  Name of the shape.
     * @param string $parentName Name of the parent/context shape.
     * @param string $ref        Name used by the context to reference the shape.
     *
     * @return null|string
     */
    public function getShapeDocs($shapeName, $parentName, $ref)
    {
        if (!isset($this->docs['shapes'][$shapeName])) {
            return '';
        }

        $result = '';
        $d = $this->docs['shapes'][$shapeName];
        if (isset($d['refs']["{$parentName}\$${ref}"])) {
            $result = $d['refs']["{$parentName}\$${ref}"];
        } elseif (isset($d['base'])) {
            $result = $d['base'];
        }

        if (isset($d['append'])) {
            if (!isset($d['excludeAppend'])
                || !in_array($parentName, $d['excludeAppend'])
            ) {
                $result .= $d['append'];
            }
        }

        if (isset($d['appendOnly'])
           && in_array($parentName, $d['appendOnly']['shapes'])
        ) {
            $result .= $d['appendOnly']['message'];
        }

        return $this->clean($result);
    }

    private function clean($content)
    {
        if (!$content) {
            return '';
        }

        $tidy = new \tidy();
        $tidy->parseString($content, [
            'indent' => true,
            'doctype' => 'omit',
            'output-html' => true,
            'show-body-only' => true,
            'drop-empty-paras' => true,
            'drop-font-tags' => true,
            'drop-proprietary-attributes' => true,
            'hide-comments' => true,
            'logical-emphasis' => true
        ]);
        $tidy->cleanRepair();

        return (string) $content;
    }
}


<?php
namespace Aws\Api;

/**
 * Represents a list shape.
 */
class ListShape extends Shape
{
    private $member;

    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $definition['type'] = 'list';
        parent::__construct($definition, $shapeMap);
    }

    /**
     * @return Shape
     * @throws \RuntimeException if no member is specified
     */
    public function getMember()
    {
        if (!$this->member) {
            if (!isset($this->definition['member'])) {
                throw new \RuntimeException('No member attribute specified');
            }
            $this->member = Shape::create(
                $this->definition['member'],
                $this->shapeMap
            );
        }

        return $this->member;
    }
}


<?php
namespace Aws\Api;

/**
 * Represents a map shape.
 */
class MapShape extends Shape
{
    /** @var Shape */
    private $value;

    /** @var Shape */
    private $key;

    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $definition['type'] = 'map';
        parent::__construct($definition, $shapeMap);
    }

    /**
     * @return Shape
     * @throws \RuntimeException if no value is specified
     */
    public function getValue()
    {
        if (!$this->value) {
            if (!isset($this->definition['value'])) {
                throw new \RuntimeException('No value specified');
            }

            $this->value = Shape::create(
                $this->definition['value'],
                $this->shapeMap
            );
        }

        return $this->value;
    }

    /**
     * @return Shape
     */
    public function getKey()
    {
        if (!$this->key) {
            $this->key = isset($this->definition['key'])
                ? Shape::create($this->definition['key'], $this->shapeMap)
                : new Shape(['type' => 'string'], $this->shapeMap);
        }

        return $this->key;
    }
}


<?php
namespace Aws\Api;

/**
 * Represents an API operation.
 */
class Operation extends AbstractModel
{
    private $input;
    private $output;
    private $errors;
    private $staticContextParams = [];
    private $contextParams;

    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $definition['type'] = 'structure';

        if (!isset($definition['http']['method'])) {
            $definition['http']['method'] = 'POST';
        }

        if (!isset($definition['http']['requestUri'])) {
            $definition['http']['requestUri'] = '/';
        }

        if (isset($definition['staticContextParams'])) {
            $this->staticContextParams = $definition['staticContextParams'];
        }

        parent::__construct($definition, $shapeMap);
        $this->contextParams = $this->setContextParams();
    }

    /**
     * Returns an associative array of the HTTP attribute of the operation:
     *
     * - method: HTTP method of the operation
     * - requestUri: URI of the request (can include URI template placeholders)
     *
     * @return array
     */
    public function getHttp()
    {
        return $this->definition['http'];
    }

    /**
     * Get the input shape of the operation.
     *
     * @return StructureShape
     */
    public function getInput()
    {
        if (!$this->input) {
            if ($input = $this['input']) {
                $this->input = $this->shapeFor($input);
            } else {
                $this->input = new StructureShape([], $this->shapeMap);
            }
        }

        return $this->input;
    }

    /**
     * Get the output shape of the operation.
     *
     * @return StructureShape
     */
    public function getOutput()
    {
        if (!$this->output) {
            if ($output = $this['output']) {
                $this->output = $this->shapeFor($output);
            } else {
                $this->output = new StructureShape([], $this->shapeMap);
            }
        }

        return $this->output;
    }

    /**
     * Get an array of operation error shapes.
     *
     * @return Shape[]
     */
    public function getErrors()
    {
        if ($this->errors === null) {
            if ($errors = $this['errors']) {
                foreach ($errors as $key => $error) {
                    $errors[$key] = $this->shapeFor($error);
                }
                $this->errors = $errors;
            } else {
                $this->errors = [];
            }
        }

        return $this->errors;
    }

    /**
     * Gets static modeled static values used for
     * endpoint resolution.
     *
     * @return array
     */
    public function getStaticContextParams()
    {
        return $this->staticContextParams;
    }

    /**
     * Gets definition of modeled dynamic values used
     * for endpoint resolution
     *
     * @return array
     */
    public function getContextParams()
    {
        return $this->contextParams;
    }

    private function setContextParams()
    {
        $members = $this->getInput()->getMembers();
        $contextParams = [];

        foreach($members as $name => $shape) {
            if (!empty($contextParam = $shape->getContextParam())) {
                $contextParams[$contextParam['name']] = [
                    'shape' => $name,
                    'type' => $shape->getType()
                ];
            }
        }
        return $contextParams;
    }
}


<?php
namespace Aws\Api;

/**
 * Represents a web service API model.
 */
class Service extends AbstractModel
{
    /** @var callable */
    private $apiProvider;

    /** @var string */
    private $serviceName;

    /** @var string */
    private $apiVersion;

    /** @var array */
    private $clientContextParams = [];

    /** @var Operation[] */
    private $operations = [];

    /** @var array */
    private $paginators = null;

    /** @var array */
    private $waiters = null;

    /** @var boolean */
    private $modifiedModel = false;

    /**
     * @param array    $definition
     * @param callable $provider
     *
     * @internal param array $definition Service description
     */
    public function __construct(array $definition, callable $provider)
    {
        static $defaults = [
            'operations' => [],
            'shapes'     => [],
            'metadata'   => [],
            'clientContextParams' => []
        ], $defaultMeta = [
            'apiVersion'       => null,
            'serviceFullName'  => null,
            'serviceId'        => null,
            'endpointPrefix'   => null,
            'signingName'      => null,
            'signatureVersion' => null,
            'protocol'         => null,
            'uid'              => null
        ];

        $definition += $defaults;
        $definition['metadata'] += $defaultMeta;
        $this->definition = $definition;
        $this->apiProvider = $provider;
        parent::__construct($definition, new ShapeMap($definition['shapes']));

        if (isset($definition['metadata']['serviceIdentifier'])) {
            $this->serviceName = $this->getServiceName();
        } else {
            $this->serviceName = $this->getEndpointPrefix();
        }
        $this->apiVersion = $this->getApiVersion();
        if (isset($definition['clientContextParams'])) {
           $this->clientContextParams = $definition['clientContextParams'];
        }
    }

    /**
     * Creates a request serializer for the provided API object.
     *
     * @param Service $api      API that contains a protocol.
     * @param string  $endpoint Endpoint to send requests to.
     *
     * @return callable
     * @throws \UnexpectedValueException
     */
    public static function createSerializer(Service $api, $endpoint)
    {
        static $mapping = [
            'json'      => Serializer\JsonRpcSerializer::class,
            'query'     => Serializer\QuerySerializer::class,
            'rest-json' => Serializer\RestJsonSerializer::class,
            'rest-xml'  => Serializer\RestXmlSerializer::class
        ];

        $proto = $api->getProtocol();

        if (isset($mapping[$proto])) {
            return new $mapping[$proto]($api, $endpoint);
        }

        if ($proto == 'ec2') {
            return new Serializer\QuerySerializer($api, $endpoint, new Serializer\Ec2ParamBuilder());
        }

        throw new \UnexpectedValueException(
            'Unknown protocol: ' . $api->getProtocol()
        );
    }

    /**
     * Creates an error parser for the given protocol.
     *
     * Redundant method signature to preserve backwards compatibility.
     *
     * @param string $protocol Protocol to parse (e.g., query, json, etc.)
     *
     * @return callable
     * @throws \UnexpectedValueException
     */
    public static function createErrorParser($protocol, Service $api = null)
    {
        static $mapping = [
            'json'      => ErrorParser\JsonRpcErrorParser::class,
            'query'     => ErrorParser\XmlErrorParser::class,
            'rest-json' => ErrorParser\RestJsonErrorParser::class,
            'rest-xml'  => ErrorParser\XmlErrorParser::class,
            'ec2'       => ErrorParser\XmlErrorParser::class
        ];

        if (isset($mapping[$protocol])) {
            return new $mapping[$protocol]($api);
        }

        throw new \UnexpectedValueException("Unknown protocol: $protocol");
    }

    /**
     * Applies the listeners needed to parse client models.
     *
     * @param Service $api API to create a parser for
     * @return callable
     * @throws \UnexpectedValueException
     */
    public static function createParser(Service $api)
    {
        static $mapping = [
            'json'      => Parser\JsonRpcParser::class,
            'query'     => Parser\QueryParser::class,
            'rest-json' => Parser\RestJsonParser::class,
            'rest-xml'  => Parser\RestXmlParser::class
        ];

        $proto = $api->getProtocol();
        if (isset($mapping[$proto])) {
            return new $mapping[$proto]($api);
        }

        if ($proto == 'ec2') {
            return new Parser\QueryParser($api, null, false);
        }

        throw new \UnexpectedValueException(
            'Unknown protocol: ' . $api->getProtocol()
        );
    }

    /**
     * Get the full name of the service
     *
     * @return string
     */
    public function getServiceFullName()
    {
        return $this->definition['metadata']['serviceFullName'];
    }

    /**
     * Get the service id
     *
     * @return string
     */
    public function getServiceId()
    {
        return $this->definition['metadata']['serviceId'];
    }

    /**
     * Get the API version of the service
     *
     * @return string
     */
    public function getApiVersion()
    {
        return $this->definition['metadata']['apiVersion'];
    }

    /**
     * Get the API version of the service
     *
     * @return string
     */
    public function getEndpointPrefix()
    {
        return $this->definition['metadata']['endpointPrefix'];
    }

    /**
     * Get the signing name used by the service.
     *
     * @return string
     */
    public function getSigningName()
    {
        return $this->definition['metadata']['signingName']
            ?: $this->definition['metadata']['endpointPrefix'];
    }

    /**
     * Get the service name.
     *
     * @return string
     */
    public function getServiceName()
    {
        return $this->definition['metadata']['serviceIdentifier'];
    }

    /**
     * Get the default signature version of the service.
     *
     * Note: this method assumes "v4" when not specified in the model.
     *
     * @return string
     */
    public function getSignatureVersion()
    {
        return $this->definition['metadata']['signatureVersion'] ?: 'v4';
    }

    /**
     * Get the protocol used by the service.
     *
     * @return string
     */
    public function getProtocol()
    {
        return $this->definition['metadata']['protocol'];
    }

    /**
     * Get the uid string used by the service
     *
     * @return string
     */
    public function getUid()
    {
        return $this->definition['metadata']['uid'];
    }

    /**
     * Check if the description has a specific operation by name.
     *
     * @param string $name Operation to check by name
     *
     * @return bool
     */
    public function hasOperation($name)
    {
        return isset($this['operations'][$name]);
    }

    /**
     * Get an operation by name.
     *
     * @param string $name Operation to retrieve by name
     *
     * @return Operation
     * @throws \InvalidArgumentException If the operation is not found
     */
    public function getOperation($name)
    {
        if (!isset($this->operations[$name])) {
            if (!isset($this->definition['operations'][$name])) {
                throw new \InvalidArgumentException("Unknown operation: $name");
            }
            $this->operations[$name] = new Operation(
                $this->definition['operations'][$name],
                $this->shapeMap
            );
        } else if ($this->modifiedModel) {
            $this->operations[$name] = new Operation(
                $this->definition['operations'][$name],
                $this->shapeMap
            );
        }

        return $this->operations[$name];
    }

    /**
     * Get all of the operations of the description.
     *
     * @return Operation[]
     */
    public function getOperations()
    {
        $result = [];
        foreach ($this->definition['operations'] as $name => $definition) {
            $result[$name] = $this->getOperation($name);
        }

        return $result;
    }

    /**
     * Get all of the error shapes of the service
     *
     * @return array
     */
    public function getErrorShapes()
    {
        $result = [];
        foreach ($this->definition['shapes'] as $name => $definition) {
            if (!empty($definition['exception'])) {
                $definition['name'] = $name;
                $result[] = new StructureShape($definition, $this->getShapeMap());
            }
        }

        return $result;
    }

    /**
     * Get all of the service metadata or a specific metadata key value.
     *
     * @param string|null $key Key to retrieve or null to retrieve all metadata
     *
     * @return mixed Returns the result or null if the key is not found
     */
    public function getMetadata($key = null)
    {
        if (!$key) {
            return $this['metadata'];
        }

        if (isset($this->definition['metadata'][$key])) {
            return $this->definition['metadata'][$key];
        }

        return null;
    }

    /**
     * Gets an associative array of available paginator configurations where
     * the key is the name of the paginator, and the value is the paginator
     * configuration.
     *
     * @return array
     * @unstable The configuration format of paginators may change in the future
     */
    public function getPaginators()
    {
        if (!isset($this->paginators)) {
            $res = call_user_func(
                $this->apiProvider,
                'paginator',
                $this->serviceName,
                $this->apiVersion
            );
            $this->paginators = isset($res['pagination'])
                ? $res['pagination']
                : [];
        }

        return $this->paginators;
    }

    /**
     * Determines if the service has a paginator by name.
     *
     * @param string $name Name of the paginator.
     *
     * @return bool
     */
    public function hasPaginator($name)
    {
        return isset($this->getPaginators()[$name]);
    }

    /**
     * Retrieve a paginator by name.
     *
     * @param string $name Paginator to retrieve by name. This argument is
     *                     typically the operation name.
     * @return array
     * @throws \UnexpectedValueException if the paginator does not exist.
     * @unstable The configuration format of paginators may change in the future
     */
    public function getPaginatorConfig($name)
    {
        static $defaults = [
            'input_token'  => null,
            'output_token' => null,
            'limit_key'    => null,
            'result_key'   => null,
            'more_results' => null,
        ];

        if ($this->hasPaginator($name)) {
            return $this->paginators[$name] + $defaults;
        }

        throw new \UnexpectedValueException("There is no {$name} "
            . "paginator defined for the {$this->serviceName} service.");
    }

    /**
     * Gets an associative array of available waiter configurations where the
     * key is the name of the waiter, and the value is the waiter
     * configuration.
     *
     * @return array
     */
    public function getWaiters()
    {
        if (!isset($this->waiters)) {
            $res = call_user_func(
                $this->apiProvider,
                'waiter',
                $this->serviceName,
                $this->apiVersion
            );
            $this->waiters = isset($res['waiters'])
                ? $res['waiters']
                : [];
        }

        return $this->waiters;
    }

    /**
     * Determines if the service has a waiter by name.
     *
     * @param string $name Name of the waiter.
     *
     * @return bool
     */
    public function hasWaiter($name)
    {
        return isset($this->getWaiters()[$name]);
    }

    /**
     * Get a waiter configuration by name.
     *
     * @param string $name Name of the waiter by name.
     *
     * @return array
     * @throws \UnexpectedValueException if the waiter does not exist.
     */
    public function getWaiterConfig($name)
    {
        // Error if the waiter is not defined
        if ($this->hasWaiter($name)) {
            return $this->waiters[$name];
        }

        throw new \UnexpectedValueException("There is no {$name} waiter "
            . "defined for the {$this->serviceName} service.");
    }

    /**
     * Get the shape map used by the API.
     *
     * @return ShapeMap
     */
    public function getShapeMap()
    {
        return $this->shapeMap;
    }

    /**
     * Get all the context params of the description.
     *
     * @return array
     */
    public function getClientContextParams()
    {
        return $this->clientContextParams;
    }

    /**
     * Get the service's api provider.
     *
     * @return callable
     */
    public function getProvider()
    {
        return $this->apiProvider;
    }

    /**
     * Get the service's definition.
     *
     * @return callable
     */
    public function getDefinition()
    {
        return $this->definition;
    }

    /**
     * Sets the service's api definition.
     * Intended for internal use only.
     *
     * @return void
     *
     * @internal
     */
    public function setDefinition($definition)
    {
        $this->definition = $definition;
        $this->modifiedModel = true;
    }

    /**
     * Denotes whether or not a service's definition has
     * been modified.  Intended for internal use only.
     *
     * @return bool
     *
     * @internal
     */
    public function isModifiedModel()
    {
        return $this->modifiedModel;
    }
}


<?php
namespace Aws\Api;

/**
 * Base class representing a modeled shape.
 */
class Shape extends AbstractModel
{
    /**
     * Get a concrete shape for the given definition.
     *
     * @param array    $definition
     * @param ShapeMap $shapeMap
     *
     * @return mixed
     * @throws \RuntimeException if the type is invalid
     */
    public static function create(array $definition, ShapeMap $shapeMap)
    {
        static $map = [
            'structure' => StructureShape::class,
            'map'       => MapShape::class,
            'list'      => ListShape::class,
            'timestamp' => TimestampShape::class,
            'integer'   => Shape::class,
            'double'    => Shape::class,
            'float'     => Shape::class,
            'long'      => Shape::class,
            'string'    => Shape::class,
            'byte'      => Shape::class,
            'character' => Shape::class,
            'blob'      => Shape::class,
            'boolean'   => Shape::class
        ];

        if (isset($definition['shape'])) {
            return $shapeMap->resolve($definition);
        }

        if (!isset($map[$definition['type']])) {
            throw new \RuntimeException('Invalid type: '
                . print_r($definition, true));
        }

        $type = $map[$definition['type']];

        return new $type($definition, $shapeMap);
    }

    /**
     * Get the type of the shape
     *
     * @return string
     */
    public function getType()
    {
        return $this->definition['type'];
    }

    /**
     * Get the name of the shape
     *
     * @return string
     */
    public function getName()
    {
        return $this->definition['name'];
    }

    /**
     * Get a context param definition.
     */
    public function getContextParam()
    {
        return $this->contextParam;
    }
}


<?php
namespace Aws\Api;

/**
 * Builds shape based on shape references.
 */
class ShapeMap
{
    /** @var array */
    private $definitions;

    /** @var Shape[] */
    private $simple;

    /**
     * @param array $shapeModels Associative array of shape definitions.
     */
    public function __construct(array $shapeModels)
    {
        $this->definitions = $shapeModels;
    }

    /**
     * Get an array of shape names.
     *
     * @return array
     */
    public function getShapeNames()
    {
        return array_keys($this->definitions);
    }

    /**
     * Resolve a shape reference
     *
     * @param array $shapeRef Shape reference shape
     *
     * @return Shape
     * @throws \InvalidArgumentException
     */
    public function resolve(array $shapeRef)
    {
        $shape = $shapeRef['shape'];

        if (!isset($this->definitions[$shape])) {
            throw new \InvalidArgumentException('Shape not found: ' . $shape);
        }

        $isSimple = count($shapeRef) == 1;
        if ($isSimple && isset($this->simple[$shape])) {
            return $this->simple[$shape];
        }

        $definition = $shapeRef + $this->definitions[$shape];
        $definition['name'] = $definition['shape'];
        if (isset($definition['shape'])) {
            unset($definition['shape']);
        }

        $result = Shape::create($definition, $this);

        if ($isSimple) {
            $this->simple[$shape] = $result;
        }

        return $result;
    }
}


<?php
namespace Aws\Api;

/**
 * Represents a structure shape and resolve member shape references.
 */
class StructureShape extends Shape
{
    /**
     * @var Shape[]
     */
    private $members;

    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $definition['type'] = 'structure';

        if (!isset($definition['members'])) {
            $definition['members'] = [];
        }

        parent::__construct($definition, $shapeMap);
    }

    /**
     * Gets a list of all members
     *
     * @return Shape[]
     */
    public function getMembers()
    {
        if (empty($this->members)) {
            $this->generateMembersHash();
        }

        return $this->members;
    }

    /**
     * Check if a specific member exists by name.
     *
     * @param string $name Name of the member to check
     *
     * @return bool
     */
    public function hasMember($name)
    {
        return isset($this->definition['members'][$name]);
    }

    /**
     * Retrieve a member by name.
     *
     * @param string $name Name of the member to retrieve
     *
     * @return Shape
     * @throws \InvalidArgumentException if the member is not found.
     */
    public function getMember($name)
    {
        $members = $this->getMembers();

        if (!isset($members[$name])) {
            throw new \InvalidArgumentException('Unknown member ' . $name);
        }

        return $members[$name];
    }

    private function generateMembersHash()
    {
        $this->members = [];

        foreach ($this->definition['members'] as $name => $definition) {
            $this->members[$name] = $this->shapeFor($definition);
        }
    }
}


<?php
namespace Aws\Api;

/**
 * Represents a timestamp shape.
 */
class TimestampShape extends Shape
{
    public function __construct(array $definition, ShapeMap $shapeMap)
    {
        $definition['type'] = 'timestamp';
        parent::__construct($definition, $shapeMap);
    }

    /**
     * Formats a timestamp value for a service.
     *
     * @param mixed  $value  Value to format
     * @param string $format Format used to serialize the value
     *
     * @return int|string
     * @throws \UnexpectedValueException if the format is unknown.
     * @throws \InvalidArgumentException if the value is an unsupported type.
     */
    public static function format($value, $format)
    {
        if ($value instanceof \DateTimeInterface) {
            $value = $value->getTimestamp();
        } elseif (is_string($value)) {
            $value = strtotime($value);
        } elseif (!is_int($value)) {
            throw new \InvalidArgumentException('Unable to handle the provided'
                . ' timestamp type: ' . gettype($value));
        }

        switch ($format) {
            case 'iso8601':
                return gmdate('Y-m-d\TH:i:s\Z', $value);
            case 'rfc822':
                return gmdate('D, d M Y H:i:s \G\M\T', $value);
            case 'unixTimestamp':
                return $value;
            default:
                throw new \UnexpectedValueException('Unknown timestamp format: '
                    . $format);
        }
    }
}


<?php
namespace Aws\Api;

use Aws;

/**
 * Validates a schema against a hash of input.
 */
class Validator
{
    private $path = [];
    private $errors = [];
    private $constraints = [];

    private static $defaultConstraints = [
        'required' => true,
        'min'      => true,
        'max'      => false,
        'pattern'  => false
    ];

    /**
     * @param array $constraints Associative array of constraints to enforce.
     *                           Accepts the following keys: "required", "min",
     *                           "max", and "pattern". If a key is not
     *                           provided, the constraint will assume false.
     */
    public function __construct(array $constraints = null)
    {
        static $assumedFalseValues = [
            'required' => false,
            'min'      => false,
            'max'      => false,
            'pattern'  => false
        ];
        $this->constraints = empty($constraints)
            ? self::$defaultConstraints
            : $constraints + $assumedFalseValues;
    }

    /**
     * Validates the given input against the schema.
     *
     * @param string $name  Operation name
     * @param Shape  $shape Shape to validate
     * @param array  $input Input to validate
     *
     * @throws \InvalidArgumentException if the input is invalid.
     */
    public function validate($name, Shape $shape, array $input)
    {
        $this->dispatch($shape, $input);

        if ($this->errors) {
            $message = sprintf(
                "Found %d error%s while validating the input provided for the "
                    . "%s operation:\n%s",
                count($this->errors),
                count($this->errors) > 1 ? 's' : '',
                $name,
                implode("\n", $this->errors)
            );
            $this->errors = [];

            throw new \InvalidArgumentException($message);
        }
    }

    private function dispatch(Shape $shape, $value)
    {
        static $methods = [
            'structure' => 'check_structure',
            'list'      => 'check_list',
            'map'       => 'check_map',
            'blob'      => 'check_blob',
            'boolean'   => 'check_boolean',
            'integer'   => 'check_numeric',
            'float'     => 'check_numeric',
            'long'      => 'check_numeric',
            'string'    => 'check_string',
            'byte'      => 'check_string',
            'char'      => 'check_string'
        ];

        $type = $shape->getType();
        if (isset($methods[$type])) {
            $this->{$methods[$type]}($shape, $value);
        }
    }

    private function check_structure(StructureShape $shape, $value)
    {
        $isDocument = (isset($shape['document']) && $shape['document']);
        $isUnion = (isset($shape['union']) && $shape['union']);
        if ($isDocument) {
            if (!$this->checkDocumentType($value)) {
                $this->addError("is not a valid document type");
                return;
            }
        } elseif ($isUnion) {
            if (!$this->checkUnion($value)) {
                $this->addError("is a union type and must have exactly one non null value");
                return;
            }
        } elseif (!$this->checkAssociativeArray($value)) {
            return;
        }

        if ($this->constraints['required'] && $shape['required']) {
            foreach ($shape['required'] as $req) {
                if (!isset($value[$req])) {
                    $this->path[] = $req;
                    $this->addError('is missing and is a required parameter');
                    array_pop($this->path);
                }
            }
        }
        if (!$isDocument) {
            foreach ($value as $name => $v) {
                if ($shape->hasMember($name)) {
                    $this->path[] = $name;
                    $this->dispatch(
                        $shape->getMember($name),
                        isset($value[$name]) ? $value[$name] : null
                    );
                    array_pop($this->path);
                }
            }
        }
    }

    private function check_list(ListShape $shape, $value)
    {
        if (!is_array($value)) {
            $this->addError('must be an array. Found '
                . Aws\describe_type($value));
            return;
        }

        $this->validateRange($shape, count($value), "list element count");

        $items = $shape->getMember();
        foreach ($value as $index => $v) {
            $this->path[] = $index;
            $this->dispatch($items, $v);
            array_pop($this->path);
        }
    }

    private function check_map(MapShape $shape, $value)
    {
        if (!$this->checkAssociativeArray($value)) {
            return;
        }

        $values = $shape->getValue();
        foreach ($value as $key => $v) {
            $this->path[] = $key;
            $this->dispatch($values, $v);
            array_pop($this->path);
        }
    }

    private function check_blob(Shape $shape, $value)
    {
        static $valid = [
            'string' => true,
            'integer' => true,
            'double' => true,
            'resource' => true
        ];

        $type = gettype($value);
        if (!isset($valid[$type])) {
            if ($type != 'object' || !method_exists($value, '__toString')) {
                $this->addError('must be an fopen resource, a '
                    . 'GuzzleHttp\Stream\StreamInterface object, or something '
                    . 'that can be cast to a string. Found '
                    . Aws\describe_type($value));
            }
        }
    }

    private function check_numeric(Shape $shape, $value)
    {
        if (!is_numeric($value)) {
            $this->addError('must be numeric. Found '
                . Aws\describe_type($value));
            return;
        }

        $this->validateRange($shape, $value, "numeric value");
    }

    private function check_boolean(Shape $shape, $value)
    {
        if (!is_bool($value)) {
            $this->addError('must be a boolean. Found '
                . Aws\describe_type($value));
        }
    }

    private function check_string(Shape $shape, $value)
    {
        if ($shape['jsonvalue']) {
            if (!self::canJsonEncode($value)) {
                $this->addError('must be a value encodable with \'json_encode\'.'
                    . ' Found ' . Aws\describe_type($value));
            }
            return;
        }

        if (!$this->checkCanString($value)) {
            $this->addError('must be a string or an object that implements '
                . '__toString(). Found ' . Aws\describe_type($value));
            return;
        }

        $value = isset($value) ? $value : '';
        $this->validateRange($shape, strlen($value), "string length");

        if ($this->constraints['pattern']) {
            $pattern = $shape['pattern'];
            if ($pattern && !preg_match("/$pattern/", $value)) {
                $this->addError("Pattern /$pattern/ failed to match '$value'");
            }
        }
    }

    private function validateRange(Shape $shape, $length, $descriptor)
    {
        if ($this->constraints['min']) {
            $min = $shape['min'];
            if ($min && $length < $min) {
                $this->addError("expected $descriptor to be >= $min, but "
                    . "found $descriptor of $length");
            }
        }

        if ($this->constraints['max']) {
            $max = $shape['max'];
            if ($max && $length > $max) {
                $this->addError("expected $descriptor to be <= $max, but "
                    . "found $descriptor of $length");
            }
        }
    }

    private function checkArray($arr)
    {
        return $this->isIndexed($arr) || $this->isAssociative($arr);
    }

    private function isAssociative($arr)
    {
        return count(array_filter(array_keys($arr), "is_string")) == count($arr);
    }

    private function isIndexed(array $arr)
    {
        return $arr == array_values($arr);
    }

    private function checkCanString($value)
    {
        static $valid = [
            'string'  => true,
            'integer' => true,
            'double'  => true,
            'NULL'    => true,
        ];

        $type = gettype($value);

        return isset($valid[$type]) ||
            ($type == 'object' && method_exists($value, '__toString'));
    }

    private function checkAssociativeArray($value)
    {
        $isAssociative = false;

        if (is_array($value)) {
            $expectedIndex = 0;
            $key = key($value);

            do {
                $isAssociative = $key !== $expectedIndex++;
                next($value);
                $key = key($value);
            } while (!$isAssociative && null !== $key);
        }

        if (!$isAssociative) {
            $this->addError('must be an associative array. Found '
                . Aws\describe_type($value));
            return false;
        }

        return true;
    }

    private function checkDocumentType($value)
    {
        if (is_array($value)) {
            $typeOfFirstKey = gettype(key($value));
            foreach ($value as $key => $val) {
               if (!$this->checkDocumentType($val) || gettype($key) != $typeOfFirstKey) {
                   return false;
               }
            }
            return $this->checkArray($value);
        }
        return is_null($value)
            || is_numeric($value)
            || is_string($value)
            || is_bool($value);
    }

    private function checkUnion($value)
    {
        if (is_array($value)) {
            $nonNullCount = 0;
            foreach ($value as $key => $val) {
                if (!is_null($val) && !(strpos($key, "@") === 0)) {
                    $nonNullCount++;
                }
            }
            return $nonNullCount == 1;
        }
        return !is_null($value);
    }

    private function addError($message)
    {
        $this->errors[] =
            implode('', array_map(function ($s) { return "[{$s}]"; }, $this->path))
            . ' '
            . $message;
    }

    private function canJsonEncode($data)
    {
        return !is_resource($data);
    }
}