Parses a YAML mapping.

@param string $mapping
@param int    &$i
@param array  $references

@return array|\stdClass

@throws ParseException When malformed inline YAML string is parsed
559405
private static function parseMapping($mapping, &$i = 0, $references = [])
    {
        $output = [];
        $len = \strlen($mapping);
        ++$i;

        // {foo: bar, bar:foo, ...}
        while ($i < $len) {
            switch ($mapping[$i]) {
                case ' ':
                case ',':
                    ++$i;
                    continue 2;
                case '}':
                    return (object) $output;
            }

            // key
            $offsetBeforeKeyParsing = $i;
            $isKeyQuoted = in_array($mapping[$i], ['"', "'"], true);
            $key = self::parseScalar($mapping, [':', ' '], $i, false, []);

            if ($offsetBeforeKeyParsing === $i) {
                throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
            }

            if (false === $i = \strpos($mapping, ':', $i)) {
                break;
            }

            if (!$isKeyQuoted) {
                $evaluatedKey = self::evaluateScalar($key, $references);

                if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) {
                    throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping);
                }
            }

            if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}'], true))) {
                throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping);
            }

            if ('<<' === $key) {
                $allowOverwrite = true;
            }

            while ($i < $len) {
                if (':' === $mapping[$i] || ' ' === $mapping[$i]) {
                    ++$i;

                    continue;
                }

                switch ($mapping[$i]) {
                    case '[':
                        // nested sequence
                        $value = self::parseSequence($mapping, $i, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ('<<' === $key) {
                            foreach ($value as $parsedValue) {
                                $output += $parsedValue;
                            }
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                            $output[$key] = $value;
                        } elseif (isset($output[$key])) {
                            throw new ParseException(\sprintf('Duplicate key "%s" detected.',
                                $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        break;
                    case '{':
                        // nested mapping
                        $value = self::parseMapping($mapping, $i, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        if ('<<' === $key) {
                            $output += $value;
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                    		$output[$key] = $value;
                        } elseif (isset($output[$key])) {
                            throw new ParseException(\sprintf('Duplicate key "%s" detected.',
                                $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        break;
                    default:
                        $value = self::parseScalar($mapping, [',', '}'], $i, true, $references);
                        // Spec: Keys MUST be unique; first one wins.
                        // Parser cannot abort this mapping earlier, since lines
                        // are processed sequentially.
                        // But overwriting is allowed when a merge node is used in current block.
                        if ('<<' === $key) {
                            $output += $value;
                        } elseif ($allowOverwrite || !isset($output[$key])) {
                            $output[$key] = $value;
                        } elseif (isset($output[$key])) {
                            throw new ParseException(\sprintf('Duplicate key "%s" detected.',
                                $key), self::$parsedLineNumber + 1, $mapping);
                        }
                        --$i;
                }
                ++$i;

                continue 2;
            }
        }

        throw new ParseException(\sprintf('Malformed inline YAML string: %s.', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename);
    }
1337876
protected function getPropertiesFromMapping(Mapping $mapping)
    {
        $properties = array_merge(
            array_combine($mapping->getProperties(), $mapping->getProperties()),
            $mapping->getAliasedProperties()
        );

        return $properties;
    }
1112725
function(mapping, i)
	{
		if ( i == undefined ) i = 0;
		var output = {};
		var len = mapping.length;
		i += 1;
		var done = false;
		var doContinue = false;

		// {foo: bar, bar:foo, ...}
		while ( i < len )
		{
			doContinue = false;
			
			switch ( mapping.charAt(i) )
			{
				case ' ':
				case ',':
					i++;
					doContinue = true;
					break;
				case '}':
					this.i = i;
					return output;
			}
			
			if ( doContinue ) continue;

			// key
			var key = this.parseScalar(mapping, [':', ' '], ['"', "'"], i, false);
			i = this.i;

			// value
			done = false;
			while ( i < len )
			{
				switch ( mapping.charAt(i) )
				{
					case '[':
						// nested sequence
						output[key] = this.parseSequence(mapping, i);
						i = this.i;
						done = true;
						break;
					case '{':
						// nested mapping
						output[key] = this.parseMapping(mapping, i);
						i = this.i;
						done = true;
						break;
					case ':':
					case ' ':
						break;
					default:
						output[key] = this.parseScalar(mapping, [',', '}'], ['"', "'"], i);
						i = this.i;
						done = true;
						i--;
				}

				++i;

				if ( done )
				{
					doContinue = true;
					break;
				}
			}
			
			if ( doContinue ) continue;
		}

		throw new YamlParseException('Malformed inline YAML string "'+mapping+'"');
	}
131532
protected function parseMappings()
    {
        $this->mappedAttributes = [];

        foreach ($this->getMaps() as $attribute => $mapping) {
            if (is_array($mapping)) {
                $this->parseImplicitMapping($mapping, $attribute);
            } else {
                $this->mappedAttributes[$attribute] = $mapping;
            }
        }
    }
1221038
private function parseMap(OutputInterface $output, array $line)
    {
        $output->write('Parsing CSV header... ');
        $map = [];
        $testLocales = [];
        $numFields = 0;
        $sourceFieldsFound = 0;
        $m = null;
        foreach ($line as $index => $field) {
            if ($index !== $numFields) {
                throw new Exception('Invalid field index: ' . $index);
            }
            if (strpos($field, ',') !== false) {
                throw new Exception('Invalid field name: ' . $field);
            }
            if (isset($this->sourceFields[$field])) {
                ++$sourceFieldsFound;
                $key = $this->sourceFields[$field];
            } elseif (preg_match($this->rxLocalizedFields, $field, $m)) {
                $mappedField = $this->localizedFields[$m[1]];
                $mappedLocale = $m[2];
                if (!isset($testLocales[$mappedLocale])) {
                    $testLocales[$mappedLocale] = [];
                }
                $testLocales[$mappedLocale][] = $mappedField;
                $key = $mappedLocale . ',' . $mappedField;
            } else {
                throw new Exception('Unknown field #' . ($index + 1) . ': ' . $field);
            }
            if (in_array($key, $map, true)) {
                throw new Exception('Duplicated field: ' . $field);
            }
            $map[$index] = $key;
            ++$numFields;
        }
        if ($sourceFieldsFound !== count($this->sourceFields)) {
            throw new Exception('Bad source fields count');
        }
        foreach ($testLocales as $id => $fields) {
            if (count($fields) !== count($this->localizedFields)) {
                throw new Exception('Bad fields count for locale ' . $id);
            }
        }
        $output->writeln('<info>done</info>');
        $this->map = $map;
        $this->numFields = $numFields;
    }
272651
private function computeReferenceChanges($mapping, $reference)
    {
        $targetClass = $this->dm->getClassMetadata(get_class($reference));
        $state = $this->getDocumentState($reference);

        switch ($state) {
            case self::STATE_NEW:
                if (!($mapping['cascade'] & ClassMetadata::CASCADE_PERSIST)) {
                    throw CascadeException::newDocumentFound(self::objToStr($reference));
                }
                $this->persistNew($targetClass, $reference);
                $this->computeChangeSet($targetClass, $reference);
                break;
            case self::STATE_DETACHED:
                throw new InvalidArgumentException('A detached document was found through a reference during cascading a persist operation: '.self::objToStr($reference, $this->dm));
        }
    }
361132
public function mapField(array $mapping)
    {
        if (isset($this->fieldMappings[$mapping['fieldName']])) {
            throw MappingException::duplicateFieldMapping($this->className, $mapping['fieldName']);
        }
        $this->fieldMappings[$mapping['fieldName']] = $mapping;
    }
195868
protected function _validateAndCompleteOneToOneMapping(array $mapping)
    {
        $mapping = $this->_validateAndCompleteAssociationMapping($mapping);

        if (isset($mapping['joinColumns']) && $mapping['joinColumns']) {
            $mapping['isOwningSide'] = true;
        }

        if ($mapping['isOwningSide']) {
            if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) {
                // Apply default join column
                $mapping['joinColumns'] = array(array(
                    'name' => $this->namingStrategy->joinColumnName($mapping['fieldName'], $this->name),
                    'referencedColumnName' => $this->namingStrategy->referenceColumnName()
                ));
            }

            $uniqueConstraintColumns = array();
            foreach ($mapping['joinColumns'] as &$joinColumn) {
                if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
                    if (count($mapping['joinColumns']) == 1) {
                        if ( ! isset($mapping['id']) || ! $mapping['id']) {
                            $joinColumn['unique'] = true;
                        }
                    } else {
                        $uniqueConstraintColumns[] = $joinColumn['name'];
                    }
                }

                if (empty($joinColumn['name'])) {
                    $joinColumn['name'] = $this->namingStrategy->joinColumnName($mapping['fieldName'], $this->name);
                }

                if (empty($joinColumn['referencedColumnName'])) {
                    $joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
                }

                if ($joinColumn['name'][0] === '`') {
                    $joinColumn['name']   = trim($joinColumn['name'], '`');
                    $joinColumn['quoted'] = true;
                }

                if ($joinColumn['referencedColumnName'][0] === '`') {
                    $joinColumn['referencedColumnName'] = trim($joinColumn['referencedColumnName'], '`');
                    $joinColumn['quoted']               = true;
                }

                $mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
                $mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName'])
                        ? $joinColumn['fieldName'] : $joinColumn['name'];
            }

            if ($uniqueConstraintColumns) {
                if ( ! $this->table) {
                    throw new RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship.");
                }
                $this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array(
                    'columns' => $uniqueConstraintColumns
                );
            }

            $mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']);
        }

        $mapping['orphanRemoval']   = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
        $mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];

        if ($mapping['orphanRemoval']) {
            unset($mapping['unique']);
        }

        if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) {
            throw MappingException::illegalInverseIdentifierAssociation($this->name, $mapping['fieldName']);
        }

        return $mapping;
    }
72423
protected function cacheMapping($mapping)
    {
        $mapping = array_filter($mapping);
        if ($mapping && !empty($mapping)) {
            $cache = SS_Cache::factory('gridfieldimporter');
            $cache->save(serialize($mapping), $this->cacheKey());
        }
    }
23119
public static function parseYaml($yaml)
    {
        if (self::$yamlParser == null) {
            self::$yamlParser = new YamlParser;
        }

        return self::$yamlParser->parse($yaml);
    }
313955
public function mapField(array $mapping)
    {
        if ( ! isset($mapping['fieldName']) && isset($mapping['name'])) {
            $mapping['fieldName'] = $mapping['name'];
        }
        if ( ! isset($mapping['fieldName'])) {
            throw MappingException::missingFieldName($this->name);
        }
        if ( ! isset($mapping['name'])) {
            $mapping['name'] = $mapping['fieldName'];
        }
        if (isset($this->fieldMappings[$mapping['fieldName']])) {
            //throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']);
        }
        if ($this->discriminatorField !== null && $this->discriminatorField == $mapping['name']) {
            throw MappingException::discriminatorFieldConflict($this->name, $this->discriminatorField);
        }
        if (isset($mapping['targetDocument']) && strpos($mapping['targetDocument'], '\\') === false && strlen($this->namespace)) {
            $mapping['targetDocument'] = $this->namespace . '\\' . $mapping['targetDocument'];
        }

        if (isset($mapping['discriminatorMap'])) {
            foreach ($mapping['discriminatorMap'] as $key => $class) {
                if (strpos($class, '\\') === false && strlen($this->namespace)) {
                    $mapping['discriminatorMap'][$key] = $this->namespace . '\\' . $class;
                }
            }
        }

        if (isset($mapping['cascade']) && isset($mapping['embedded'])) {
            throw MappingException::cascadeOnEmbeddedNotAllowed($this->name, $mapping['fieldName']);
        }

        $cascades = isset($mapping['cascade']) ? array_map('strtolower', (array) $mapping['cascade']) : array();

        if (in_array('all', $cascades) || isset($mapping['embedded'])) {
            $cascades = array('remove', 'persist', 'refresh', 'merge', 'detach');
        }

        if (isset($mapping['embedded'])) {
            unset($mapping['cascade']);
        } elseif (isset($mapping['cascade'])) {
            $mapping['cascade'] = $cascades;
        }

        $mapping['isCascadeRemove'] = in_array('remove', $cascades);
        $mapping['isCascadePersist'] = in_array('persist', $cascades);
        $mapping['isCascadeRefresh'] = in_array('refresh', $cascades);
        $mapping['isCascadeMerge'] = in_array('merge', $cascades);
        $mapping['isCascadeDetach'] = in_array('detach', $cascades);

        if (isset($mapping['type']) && $mapping['type'] === 'file') {
            $mapping['file'] = true;
        }
        if (isset($mapping['file']) && $mapping['file'] === true) {
            $this->file = $mapping['fieldName'];
            $mapping['name'] = 'file';
        }
        if (isset($mapping['distance']) && $mapping['distance'] === true) {
            $this->distance = $mapping['fieldName'];
        }
        if (isset($mapping['id']) && $mapping['id'] === true) {
            $mapping['name'] = '_id';
            $mapping['type'] = isset($mapping['type']) ? $mapping['type'] : 'id';
            $this->identifier = $mapping['fieldName'];
            if (isset($mapping['strategy'])) {
                $this->generatorOptions = isset($mapping['options']) ? $mapping['options'] : array();

                $generatorType = constant('Doctrine\ODM\MongoDB\Mapping\ClassMetadata::GENERATOR_TYPE_' . strtoupper($mapping['strategy']));
                if ($generatorType !== self::GENERATOR_TYPE_AUTO) {
                    if (isset($this->generatorOptions['type'])) {
                        $mapping['type'] = $this->generatorOptions['type'];
                    } elseif ($generatorType === ClassMetadata::GENERATOR_TYPE_INCREMENT) {
                        $mapping['type'] = 'int_id';
                    } else {
                        $mapping['type'] = 'custom_id';
                    }

                    unset($this->generatorOptions['type']);
                }

                $this->generatorType = $generatorType;
            }
        }
        if ( ! isset($mapping['nullable'])) {
            $mapping['nullable'] = false;
        }

        if (isset($mapping['reference']) && ! empty($mapping['simple']) && ! isset($mapping['targetDocument'])) {
            throw MappingException::simpleReferenceRequiresTargetDocument($this->name, $mapping['fieldName']);
        }

        if (isset($mapping['reference']) && $mapping['type'] === 'one') {
            $mapping['association'] = self::REFERENCE_ONE;
        }
        if (isset($mapping['reference']) && $mapping['type'] === 'many') {
            $mapping['association'] = self::REFERENCE_MANY;
        }
        if (isset($mapping['embedded']) && $mapping['type'] === 'one') {
            $mapping['association'] = self::EMBED_ONE;
        }
        if (isset($mapping['embedded']) && $mapping['type'] === 'many') {
            $mapping['association'] = self::EMBED_MANY;
        }

        if (isset($mapping['association']) && ! isset($mapping['targetDocument']) && ! isset($mapping['discriminatorField'])) {
            $mapping['discriminatorField'] = self::DEFAULT_DISCRIMINATOR_FIELD;
        }

        /*
        if (isset($mapping['type']) && ($mapping['type'] === 'one' || $mapping['type'] === 'many')) {
            $mapping['type'] = $mapping['type'] === 'one' ? self::ONE : self::MANY;
        }
        */
        if (isset($mapping['version'])) {
            $mapping['notSaved'] = true;
            $this->setVersionMapping($mapping);
        }
        if (isset($mapping['lock'])) {
            $mapping['notSaved'] = true;
            $this->setLockMapping($mapping);
        }
        $mapping['isOwningSide'] = true;
        $mapping['isInverseSide'] = false;
        if (isset($mapping['reference'])) {
            if (isset($mapping['inversedBy']) && $mapping['inversedBy']) {
                $mapping['isOwningSide'] = true;
                $mapping['isInverseSide'] = false;
            }
            if (isset($mapping['mappedBy']) && $mapping['mappedBy']) {
                $mapping['isInverseSide'] = true;
                $mapping['isOwningSide'] = false;
            }
            if (!isset($mapping['orphanRemoval'])) {
                $mapping['orphanRemoval'] = false;
            }
        }

        $this->fieldMappings[$mapping['fieldName']] = $mapping;
        if (isset($mapping['association'])) {
            $this->associationMappings[$mapping['fieldName']] = $mapping;
        }

        return $mapping;
    }
458757
private function determineMaxValue(array $mapping)
    {
        if (!isset($mapping['precision']) && !isset($mapping['scale'])) {
            return null;
        }

        $scale = isset($mapping['scale']) ? (int)$mapping['scale'] : 0;
        $precision = isset($mapping['precision']) ? (int)$mapping['precision'] : 0;
        if ($precision < $scale) {
            $precision = $scale;
        }

        $maxValueStr = (int)str_repeat('9', $precision);
        $integerPartLength = $precision - $scale;

        $fractionalPart = substr($maxValueStr, 0, $integerPartLength);
        $integerPart = substr($maxValueStr, $integerPartLength);
        $maxValue = (float)"$fractionalPart.$integerPart";

        return $maxValue;
    }
989149
public function mapManyToOne(array $mapping)
    {
        $mapping['type'] = self::MANY_TO_ONE;
        // A many-to-one mapping is essentially a one-one backreference
        $mapping = $this->_validateAndCompleteOneToOneMapping($mapping);
        $this->_storeAssociationMapping($mapping);
    }
1096277
public function validateReferences()
    {
        foreach ($this->referenceMappings as $fieldName) {
            $mapping = $this->mappings[$fieldName];
            if (!empty($mapping['targetDocument']) && !ClassLoader::classExists($mapping['targetDocument'])) {
                throw MappingException::invalidTargetDocumentClass($mapping['targetDocument'], $this->name, $mapping['fieldName']);
            }
        }
    }
1060149
public function setVersionMapping(array &$mapping)
    {
        $this->isVersioned = true;
        $this->versionField = $mapping['fieldName'];

        if ( ! isset($mapping['default'])) {
            if (in_array($mapping['type'], array('integer', 'bigint', 'smallint'))) {
                $mapping['default'] = 1;
            } else if ($mapping['type'] == 'datetime') {
                $mapping['default'] = 'CURRENT_TIMESTAMP';
            } else {
                throw MappingException::unsupportedOptimisticLockingType($this->name, $mapping['fieldName'], $mapping['type']);
            }
        }
    }
1266715
protected function _validateAndCompleteFieldMapping(array &$mapping)
    {
        // Check mandatory fields
        if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) {
            throw MappingException::missingFieldName($this->name);
        }
        if ( ! isset($mapping['type'])) {
            // Default to string
            $mapping['type'] = 'string';
        }

        // Complete fieldName and columnName mapping
        if ( ! isset($mapping['columnName'])) {
            $mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName'], $this->name);
        }

        if ($mapping['columnName'][0] === '`') {
            $mapping['columnName']  = trim($mapping['columnName'], '`');
            $mapping['quoted']      = true;
        }

        $this->columnNames[$mapping['fieldName']] = $mapping['columnName'];
        if (isset($this->fieldNames[$mapping['columnName']]) || ($this->discriminatorColumn != null && $this->discriminatorColumn['name'] == $mapping['columnName'])) {
            throw MappingException::duplicateColumnName($this->name, $mapping['columnName']);
        }

        $this->fieldNames[$mapping['columnName']] = $mapping['fieldName'];

        // Complete id mapping
        if (isset($mapping['id']) && $mapping['id'] === true) {
            if ($this->versionField == $mapping['fieldName']) {
                throw MappingException::cannotVersionIdField($this->name, $mapping['fieldName']);
            }

            if ( ! in_array($mapping['fieldName'], $this->identifier)) {
                $this->identifier[] = $mapping['fieldName'];
            }
            // Check for composite key
            if ( ! $this->isIdentifierComposite && count($this->identifier) > 1) {
                $this->isIdentifierComposite = true;
            }
        }

        if (Type::hasType($mapping['type']) && Type::getType($mapping['type'])->canRequireSQLConversion()) {
            if (isset($mapping['id']) && $mapping['id'] === true) {
                 throw MappingException::sqlConversionNotAllowedForIdentifiers($this->name, $mapping['fieldName'], $mapping['type']);
            }

            $mapping['requireSQLConversion'] = true;
        }
    }
212575
public function setDiscriminatorMap(array $map)
    {
        foreach ($map as $value => $className) {
            if (strpos($className, '\\') === false && strlen($this->namespace)) {
                $className = $this->namespace . '\\' . $className;
            }
            $this->discriminatorMap[$value] = $className;
            if ($this->name == $className) {
                $this->discriminatorValue = $value;
            } else {
                if ( ! class_exists($className)) {
                    throw MappingException::invalidClassInDiscriminatorMap($className, $this->name);
                }
                if (is_subclass_of($className, $this->name)) {
                    $this->subClasses[] = $className;
                }
            }
        }
    }