public MergeResult merge(Mapping mapping, boolean simulate, boolean updateAllTypes) {
   try (ReleasableLock lock = mappingWriteLock.acquire()) {
     final MergeResult mergeResult = new MergeResult(simulate, updateAllTypes);
     this.mapping.merge(mapping, mergeResult);
     if (simulate == false) {
       addMappers(mergeResult.getNewObjectMappers(), mergeResult.getNewFieldMappers());
       refreshSource();
     }
     return mergeResult;
   }
 }
 public DocumentMapper merge(
     String type, CompressedXContent mappingSource, boolean applyDefault, boolean updateAllTypes) {
   if (DEFAULT_MAPPING.equals(type)) {
     // verify we can parse it
     DocumentMapper mapper = documentParser.parseCompressed(type, mappingSource);
     // still add it as a document mapper so we have it registered and, for example, persisted back
     // into
     // the cluster meta data if needed, or checked for existence
     try (ReleasableLock lock = mappingWriteLock.acquire()) {
       mappers = newMapBuilder(mappers).put(type, mapper).map();
     }
     try {
       defaultMappingSource = mappingSource.string();
     } catch (IOException e) {
       throw new ElasticsearchGenerationException("failed to un-compress", e);
     }
     return mapper;
   } else {
     return merge(parse(type, mappingSource, applyDefault), updateAllTypes);
   }
 }
 public ParsedDocument parseDocument(SourceToParse source) throws MapperParsingException {
   try (ReleasableLock lock = parseLock.acquire()) {
     return innerParseDocument(source);
   }
 }
  // never expose this to the outside world, we need to reparse the doc mapper so we get fresh
  // instances of field mappers to properly remove existing doc mapper
  private DocumentMapper merge(DocumentMapper mapper, boolean updateAllTypes) {
    try (ReleasableLock lock = mappingWriteLock.acquire()) {
      if (mapper.type().length() == 0) {
        throw new InvalidTypeNameException("mapping type name is empty");
      }
      if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)
          && mapper.type().length() > 255) {
        throw new InvalidTypeNameException(
            "mapping type name ["
                + mapper.type()
                + "] is too long; limit is length 255 but was ["
                + mapper.type().length()
                + "]");
      }
      if (mapper.type().charAt(0) == '_') {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] can't start with '_'");
      }
      if (mapper.type().contains("#")) {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] should not include '#' in it");
      }
      if (mapper.type().contains(",")) {
        throw new InvalidTypeNameException(
            "mapping type name [" + mapper.type() + "] should not include ',' in it");
      }
      if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)
          && mapper.type().equals(mapper.parentFieldMapper().type())) {
        throw new IllegalArgumentException(
            "The [_parent.type] option can't point to the same type");
      }
      if (typeNameStartsWithIllegalDot(mapper)) {
        if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)) {
          throw new IllegalArgumentException(
              "mapping type name [" + mapper.type() + "] must not start with a '.'");
        } else {
          logger.warn(
              "Type [{}] starts with a '.', it is recommended not to start a type name with a '.'",
              mapper.type());
        }
      }
      // we can add new field/object mappers while the old ones are there
      // since we get new instances of those, and when we remove, we remove
      // by instance equality
      DocumentMapper oldMapper = mappers.get(mapper.type());

      if (oldMapper != null) {
        MergeResult result = oldMapper.merge(mapper.mapping(), false, updateAllTypes);
        if (result.hasConflicts()) {
          // TODO: What should we do???
          if (logger.isDebugEnabled()) {
            logger.debug(
                "merging mapping for type [{}] resulted in conflicts: [{}]",
                mapper.type(),
                Arrays.toString(result.buildConflicts()));
          }
        }
        return oldMapper;
      } else {
        List<ObjectMapper> newObjectMappers = new ArrayList<>();
        List<FieldMapper> newFieldMappers = new ArrayList<>();
        for (MetadataFieldMapper metadataMapper : mapper.mapping().metadataMappers) {
          newFieldMappers.add(metadataMapper);
        }
        MapperUtils.collect(mapper.mapping().root, newObjectMappers, newFieldMappers);
        checkNewMappersCompatibility(newObjectMappers, newFieldMappers, updateAllTypes);
        addMappers(newObjectMappers, newFieldMappers);

        for (DocumentTypeListener typeListener : typeListeners) {
          typeListener.beforeCreate(mapper);
        }
        mappers = newMapBuilder(mappers).put(mapper.type(), mapper).map();
        if (mapper.parentFieldMapper().active()) {
          ImmutableSet.Builder<String> parentTypesCopy = ImmutableSet.builder();
          parentTypesCopy.addAll(parentTypes);
          parentTypesCopy.add(mapper.parentFieldMapper().type());
          parentTypes = parentTypesCopy.build();
        }
        assert assertSerialization(mapper);
        return mapper;
      }
    }
  }