private function splitTraceState()

in agent/php/ElasticApm/Impl/HttpDistributedTracing.php [333:410]


    private function splitTraceState(
        array $headerRawValues,
        ?string &$elasticVendorValue,
        ?string &$otherVendorsKeyValuePairs
    ): bool {
        $localLogger = $this->logger->inherit();
        $localLogger->addContext('headerRawValues', $headerRawValues);

        /** @var array<string, string> */
        $encounteredKeyToValue = [];
        $maxAllowedRemainingPairsCount = self::TRACE_STATE_MAX_PAIRS_COUNT;
        foreach ($headerRawValues as $headerRawValue) {
            $keyValuePairs = explode(
                self::TRACE_STATE_KEY_VALUE_PAIRS_SEPARATOR,
                $headerRawValue,
                /* limit: */ $maxAllowedRemainingPairsCount + 1
            );
            foreach ($keyValuePairs as $keyValuePair) {
                $keyValuePair = trim($keyValuePair);
                if (TextUtil::isEmptyString($keyValuePair)) {
                    continue;
                }
                if ($maxAllowedRemainingPairsCount === 0) {
                    ($loggerProxy = $localLogger->ifDebugLevelEnabled(__LINE__, __FUNCTION__))
                    && $loggerProxy->log(
                        'Number of found pairs in ' . self::TRACE_STATE_HEADER_NAME . ' HTTP header '
                        . ' is more than allowed maximum (' . self::TRACE_STATE_MAX_PAIRS_COUNT . ')'
                        . ' - only the first ' . self::TRACE_STATE_MAX_PAIRS_COUNT . ' pairs will be used',
                        [
                            'keyValuePair'          => $keyValuePair,
                            'encounteredKeyToValue' => $encounteredKeyToValue,
                            'headerRawValue'        => $headerRawValue,
                        ]
                    );
                    return true;
                }

                /** @var string */
                $key = '';
                /** @var string */
                $value = '';
                if (!$this->splitTraceStateKeyValuePair($keyValuePair, $key, $value)) {
                    return false;
                }

                if (array_key_exists($key, $encounteredKeyToValue)) {
                    ($loggerProxy = $localLogger->ifDebugLevelEnabled(__LINE__, __FUNCTION__))
                    && $loggerProxy->log(
                        'Encountered key more than once',
                        [
                            'key'                   => $key,
                            'keyValuePair'          => $keyValuePair,
                            'encounteredKeyToValue' => $encounteredKeyToValue,
                        ]
                    );
                    return false;
                }

                $encounteredKeyToValue[$key] = $value;

                if ($key === self::TRACE_STATE_ELASTIC_VENDOR_KEY) {
                    $elasticVendorValue = $value;
                } else {
                    if ($otherVendorsKeyValuePairs === null) {
                        $otherVendorsKeyValuePairs = '';
                    }
                    self::appendKeyValuePairToTraceState(
                        $key . self::TRACE_STATE_KEY_VALUE_SEPARATOR . $value,
                        $otherVendorsKeyValuePairs /* <- ref */
                    );
                }

                --$maxAllowedRemainingPairsCount;
            }
        }

        return true;
    }