Exemplo n.º 1
0
Arquivo: field.c Projeto: norstc/ctags
static void printField (fieldType i)
{
	unsigned char letter = fieldDescs[i].spec->letter;
	const char *name;
	const char *language;

	if (letter == FIELD_LETTER_NO_USE)
		letter = '-';

	if (! fieldDescs[i].spec->name)
		name = "NONE";
	else
		name = getFieldName (i);

	if (fieldDescs[i].language == LANG_IGNORE)
		language = "NONE";
	else
		language = getLanguageName (fieldDescs[i].language);

	printf((Option.machinable? "%c\t%s\t%s\t%s\t%s\t%s\n": MAKE_FIELD_FMT(c)),
	       letter,
	       name,
	       isFieldEnabled (i)? "on": "off",
	       language,
	       getFieldDesc (i)->spec->renderEscaped? "TRUE": "FALSE",
	       fieldDescs[i].spec->description? fieldDescs[i].spec->description: "NONE");
}
Exemplo n.º 2
0
std::ostream& PVStructure::dumpValue(std::ostream& o) const
{
    o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
    String extendsName = getExtendsStructureName();
    if(extendsName.length()>0) {
        o << " extends " << extendsName;
    }
    o << std::endl;
    {
    	format::indent_scope s(o);

		PVFieldPtrArray const & fieldsData = getPVFields();
		if (fieldsData.size() != 0) {
			size_t length = getStructure()->getNumberFields();
			for(size_t i=0; i<length; i++) {
				PVFieldPtr fieldField = fieldsData[i];
				Type type = fieldField->getField()->getType();
				if (type == scalar || type == scalarArray)
					o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
				else
					o << *(fieldField.get());
			}
		}
    }
 	return o;
}
Exemplo n.º 3
0
std::string Element::toString() const {
    if (!ok())
        return "INVALID-MUTABLE-ELEMENT";

    if (hasValue())
        return getValue().toString();

    const BSONType type = getType();

    // The only types that sometimes don't have a value are Object and Array nodes.
    dassert((type == mongo::Object) || (type == mongo::Array));

    if (type == mongo::Object) {
        BSONObjBuilder builder;
        writeTo(&builder);
        BSONObj obj = builder.obj();
        return obj.firstElement().toString();
    } else {
        // It must be an array.
        BSONObjBuilder builder;
        BSONArrayBuilder arrayBuilder(builder.subarrayStart(getFieldName()));
        writeArrayTo(&arrayBuilder);
        arrayBuilder.done();
        BSONObj obj = builder.obj();
        return obj.firstElement().toString();
    }
}
Exemplo n.º 4
0
bool GuiInspectorDynamicField::onAdd()
{
   if( !Parent::onAdd() )
      return false;

   //pushObjectToBack(mEdit);

   // Create our renaming field
   mRenameCtrl = new GuiTextEditCtrl();
   mRenameCtrl->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorDynamicFieldProfile" );

   char szName[512];
   dSprintf( szName, 512, "IE_%s_%d_%s_Rename", mRenameCtrl->getClassName(), mInspector->getInspectObject()->getId(), getFieldName() );
   mRenameCtrl->registerObject( szName );

   // Our command will evaluate to :
   //
   //    if( (editCtrl).getText() !$= "" )
   //       (field).renameField((editCtrl).getText());
   //
   char szBuffer[1024];
   dSprintf( szBuffer, sizeof( szBuffer ), "if( %d.getText() !$= \"\" ) %d.renameField(%d.getText());", mRenameCtrl->getId(), getId(), mRenameCtrl->getId() );
   mRenameCtrl->setText( getFieldName() );
   mRenameCtrl->setField("Validate", szBuffer );
   addObject( mRenameCtrl );

   // Resize the name control to fit in our caption rect
   mRenameCtrl->resize( mCaptionRect.point, mCaptionRect.extent );

   // Resize the value control to leave space for the delete button
   mEdit->resize( mValueRect.point, mValueRect.extent);

   // Clear out any caption set from Parent::onAdd
   // since we are rendering the fieldname with our 'rename' control.
   mCaption = StringTable->insert( "" );

   // Create delete button control
   mDeleteButton = new GuiBitmapButtonCtrl();

	SimObject* profilePtr = Sim::findObject("InspectorDynamicFieldButton");
   if( profilePtr != NULL )
		mDeleteButton->setControlProfile( dynamic_cast<GuiControlProfile*>(profilePtr) );

   dSprintf( szBuffer, sizeof( szBuffer ),
      "%d.apply(\"\");%d.schedule(1,\"inspectGroup\");",
      getId(),
      mParent->getId() );

   // FIXME Hardcoded image
   mDeleteButton->setField( "Bitmap", "tools/gui/images/iconDelete" );
   mDeleteButton->setField( "Text", "X" );
   mDeleteButton->setField( "Command", szBuffer );
   mDeleteButton->setSizing( horizResizeLeft, vertResizeCenter );
	mDeleteButton->resize(Point2I(getWidth() - 20,2), Point2I(16, 16));
   mDeleteButton->registerObject();

   addObject(mDeleteButton);

   return true;
}
int csimClass::setFieldById(char *o, int id, double *v)
{
    if ( id < 0 || id >= getClassInfo()->nRegFields )
    {
        TheCsimError.add("csimClass::setFieldById: invalid field Id (%i) for class %s\n",id,className());
        return -1;
    }

    csimFieldInfo *fi=getClassInfo()->regFields[id];

    if ( fi->access != READWRITE )
    {
        TheCsimError.add("csimClass::setFieldById: field %s is READONLY!\n",getFieldName(id));
        return -1;
    }

    int i;

    //  printf("%i %i %i\n",fi->ff,fi->df,fi->intf);

    switch ( fi->fieldType ) {
    case FLOATFIELD:
        *((float *)(o+(fi->offset))) = (float)(*v);
        break;

    case DOUBLEFIELD:
        *((double *)(o+(fi->offset))) = (double)(*v);
        break;

    case INTFIELD:
        *((int *)(o+(fi->offset))) = (int)(*v);
        break;

    case FLOATARRAY:
        for(i=0; i<fi->m; i++) {
            (*(*((float **)(o+(fi->offset)))+i)) = (float)v[i];
        }
        break;

    case DOUBLEARRAY:
        memcpy(*((double **)(o+(fi->offset))),v,fi->m*sizeof(double));
        break;

    case INTARRAY:
        for(i=0; i<fi->m; i++) {
            (*(*((int **)(o+(fi->offset)))+i)) = (int)v[i];
        }
        break;

    default: {
        TheCsimError.add("csimClass::setFieldById: internal error this should not happen!!\n");
        return -1;
    }
    }

    dirty = 1;

    return 0;
}
Exemplo n.º 6
0
static void printField (fieldType i)
{
	printf("%c\t%s\t%s\t%s\t%s\n",
	       fieldDescs[i].letter,
	       (fieldDescs[i].name? getFieldName (i): "NONE"),
	       fieldDescs[i].description? fieldDescs[i].description: "NONE",
	       getFieldDesc (i)->renderEscaped? "format-char": "NONE",
	       getFieldDesc (i)->enabled? "on": "off");
}
Exemplo n.º 7
0
void AddFieldDlg::accept()
{
   if (getFieldName().isEmpty())
   {
      QMessageBox::critical(this, windowTitle(), "Please enter a valid field name!");
      return;
   }

   QDialog::accept();
}
		TITANIUM_FUNCTION(ResultSet, getFieldName)
		{
			ENSURE_UINT_AT_INDEX(index, 0);

			const std::string result = getFieldName(index);
			if (result == nullptr) {
				return get_context().CreateNull();
			}
			return get_context().CreateString(result);
		}
Exemplo n.º 9
0
// Find field with name fieldName in object
// NULL if field not found
GvField*
GvFieldData::getField(const GvNode *object,const char * fieldName) const
{
    for (int i = 0; i < fields.getLength(); i++) {
	    if (getFieldName(i) == fieldName) {
	        return(getField(object,i));
	    }
    }
    return(NULL);
}
Exemplo n.º 10
0
// Find field with name fieldName in object, Result -1 if not found
int
GvFieldData::getFieldIndex(const char * fieldName) const
{
    for (int i = 0; i < fields.getLength(); i++) {
	    if (getFieldName(i) == fieldName) {
	        return(i);
	    }
    }
    return(-1);
}
Exemplo n.º 11
0
void ParsedExclusionProjection::parse(const boost::intrusive_ptr<ExpressionContext>& expCtx,
                                      const BSONObj& spec,
                                      ExclusionNode* node,
                                      size_t depth) {
    for (auto elem : spec) {
        const auto fieldName = elem.fieldNameStringData().toString();

        // A $ should have been detected in ParsedAggregationProjection's parsing before we get
        // here.
        invariant(fieldName[0] != '$');

        switch (elem.type()) {
            case BSONType::Bool:
            case BSONType::NumberInt:
            case BSONType::NumberLong:
            case BSONType::NumberDouble:
            case BSONType::NumberDecimal: {
                // We have already verified this is an exclusion projection.
                invariant(!elem.trueValue());

                node->excludePath(FieldPath(fieldName));
                break;
            }
            case BSONType::Object: {
                // This object represents a nested projection specification, like the sub-object in
                // {a: {b: 0, c: 0}} or {"a.b": {c: 0}}.
                ExclusionNode* child;

                if (elem.fieldNameStringData().find('.') == std::string::npos) {
                    child = node->addOrGetChild(fieldName);
                } else {
                    // A dotted field is not allowed in a sub-object, and should have been detected
                    // in ParsedAggregationProjection's parsing before we get here.
                    invariant(depth == 0);

                    // We need to keep adding children to our tree until we create a child that
                    // represents this dotted path.
                    child = node;
                    auto fullPath = FieldPath(fieldName);
                    while (fullPath.getPathLength() > 1) {
                        child = child->addOrGetChild(fullPath.getFieldName(0));
                        fullPath = fullPath.tail();
                    }
                    // It is illegal to construct an empty FieldPath, so the above loop ends one
                    // iteration too soon. Add the last path here.
                    child = child->addOrGetChild(fullPath.fullPath());
                }

                parse(expCtx, elem.Obj(), child, depth + 1);
                break;
            }
            default: { MONGO_UNREACHABLE; }
        }
    }
}
Exemplo n.º 12
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int QualityMetricFilter::filter()
{
  int err = 0;
  if (m_Output.get() == NULL)
  {
    m_Output = DataArray<bool>::CreateArray(0, getFieldName());
  }
  m_Output->Resize(m_NumValues);
  m_Output->initializeWithZeros();

  if (m_DataType == Ebsd::Int8)
  {
    FILTER_DATA(int8_t);
  }
  if (m_DataType == Ebsd::UInt8)
  {
    FILTER_DATA(uint8_t);
  }
  if (m_DataType == Ebsd::Int16)
  {
    FILTER_DATA(int16_t);
  }
  if (m_DataType == Ebsd::UInt16)
  {
    FILTER_DATA(uint16_t);
  }
  if (m_DataType == Ebsd::Int32)
  {
    FILTER_DATA(int32_t);
  }
  if (m_DataType == Ebsd::UInt32)
  {
    FILTER_DATA(uint32_t);
  }
  if (m_DataType == Ebsd::Int64)
  {
    FILTER_DATA(int64_t);
  }
  if (m_DataType == Ebsd::UInt64)
  {
    FILTER_DATA(uint64_t);
  }
  if (m_DataType == Ebsd::Float)
  {
    FILTER_DATA(float);
  }
  if (m_DataType == Ebsd::Double)
  {
    FILTER_DATA(double);
  }


  return err;
}
Exemplo n.º 13
0
void Logger::writeMetaData ()
{
	//_fileStream << getNumberOfFields() << " ";
	for (unsigned int i=0; i < getNumberOfFields(); i++)
	{
		_fileStream << getFieldName(i) << " ";
		_fileStream << getFieldDataType(i) << " ";
	}
	_fileStream << "\n";

}
Exemplo n.º 14
0
GvName GvFieldData::getEventInName(int index) const
{
	const GvName &n = getFieldName(index);
    GvFieldEntry *fieldEntry = getFieldEntry(index);

	if (fieldEntry->type /* getType()*/ <= GV_EXPOSED_FIELD) {
		GvString s("set_");
		s+=n.getString();
		return(GvName(s));
	} else return n;
}
Exemplo n.º 15
0
//*************************************************************************************************
// PlanetNoiseParameter
//*************************************************************************************************
void PlanetNoiseParameter::print(bool toLog /*= false*/)
{
    if(toLog)
    {
        DREngineLog.writeToLog("----- PlanetNoiseParameter Begin ----");
        for(int i = 0; i < 21; i++)
        {
            DREngineLog.writeToLog("%s: %.4f", getFieldName(static_cast<PlanetNoiseParameterNames>(i)), values[i]);
        }
        DREngineLog.writeToLog("----- PlanetNoiseParameter Ende ----");
    }
    else
    {
        printf("----- PlanetNoiseParameter Begin ----");
        for(int i = 0; i < 21; i++)
        {
            printf("%s: %.4f", getFieldName(static_cast<PlanetNoiseParameterNames>(i)), values[i]);
        }
        printf("----- PlanetNoiseParameter Ende ----");
    }
}
Exemplo n.º 16
0
std::string Logger::getMetaData ()
{
	//_fileStream << getNumberOfFields() << " ";
	std::stringstream ss;
	for (unsigned int i=0; i < getNumberOfFields(); i++)
	{
		ss << getFieldName(i) << " ";
		ss << getFieldDataType(i) << " ";
	}
	ss << "\n";
	return ss.str();

}
Exemplo n.º 17
0
GvName GvFieldData::getEventOutName(int index) const
{
	const GvName &n = getFieldName(index);
    GvFieldEntry *fieldEntry = getFieldEntry(index);

	if (fieldEntry->type /*getType()*/ <= GV_EXPOSED_FIELD) {
		GvString s(n.getString());
		s+="_changed";
		return(GvName(s));
	}
	else return(n);

}
Exemplo n.º 18
0
std::ostream& PVUnionArray::dumpValue(std::ostream& o) const
{
    o << format::indent() << getUnionArray()->getID() << ' ' << getFieldName() << std::endl;
    size_t length = getLength();
    if (length > 0)
    {
    	format::indent_scope s(o);

        for (size_t i = 0; i < length; i++)
        	dumpValue(o, i);
    }

    return o;
}
Exemplo n.º 19
0
static void addParserFields (json_t *response, const tagEntryInfo *const tag)
{
	unsigned int i;
	unsigned int ftype;

	for (i = 0; i < tag->usedParserFields; i++)
	{
		ftype = tag->parserFields [i].ftype;
		if (! isFieldEnabled (ftype))
			continue;

		json_object_set_new (response, getFieldName (ftype), json_string (tag->parserFields [i].value));
	}
}
Exemplo n.º 20
0
void GuiInspectorField::setInspectorField( AbstractClassRep::Field *field, StringTableEntry caption, const char*arrayIndex ) 
{
   mField = field; 

   if ( arrayIndex != NULL )   
      mFieldArrayIndex = StringTable->insert( arrayIndex );

   if ( !caption || !caption[0] )
      mCaption = getFieldName(); 
   else
      mCaption = caption;
      
   _setFieldDocs( mField->pFieldDocs );
}
osg::Real32 FieldAnimationAdvancer::getValue(void) const
{
   if(getFieldId() == 0)
   {
      //Check if the Field Container is defined
      if(getContainer() == osg::NullFC)
      {
         SWARNING << "There is no Field Container defined to get Field Advancer"  << std::endl;
         return 0.0f;
      }
      //Check if the field in this container is defined
      FieldDescription * f = getContainer()->getType().findFieldDescription(getFieldName().c_str());
      if( f == NULL )
      {
         SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
         return 0.0f;
      }
      //Found the Field so set my Field Id
      beginEditCP(FieldAnimationAdvancerPtr(this), FieldIdFieldMask);
         const_cast<SFUInt32*>(&_sfFieldId)->setValue(f->getFieldId());
      endEditCP(FieldAnimationAdvancerPtr(this), FieldIdFieldMask);
      //The Field was not found
      if(getFieldId() == 0)
      {
         SWARNING << "Could not find Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName()  << std::endl;
         return 0.0f;
      }
      //Check if the field is a Real32
      if(getContainer()->getField( getFieldId() )->getType() != SFReal32::getClassType())
      {
         SWARNING << "Field "<< getFieldName() << " in Field Container " << getContainer()->getTypeName() << "Is not a SFReal32 Field."  << std::endl;
         return 0.0f;
      }
   }
   
   return static_cast<SFReal32*>(getContainer()->getField( getFieldId() ))->getValue();
}
Exemplo n.º 22
0
void FieldDefinition::fromByteArray(char *source, int buffSize)
{
    if(buffSize < 62) return;

    memcpy(&fieldType, source, 4);
    memcpy(&fieldSize, &source[4], 4);
    memcpy(&is_Key, &source[8], 4);
    memcpy(name, &source[12], 50);

    cout << "\nF-Type: " << fieldType;
    cout << "\nF-Size: " << fieldSize;
    cout << "\nF-Key: " << is_Key;
    cout << "\nF-name: " << getFieldName();

}
Exemplo n.º 23
0
/**
* Equivalent to MOItem::toXmlData() but here, we do not save
* index field. Because if index changed (e.g. order is changed between two versions),
* there would be misunderstanding to keep index. Name is the field used to refer.
* @sa MOItem::toXmlData()
*/
QDomElement MOParameter::toXmlData(QDomDocument & doc)
{
    QDomElement cItem = doc.createElement(this->getClassName());
    QString fieldName;
    QString fieldValue;
    for(int iF=0;iF<getNbFields();iF++)
    {
        //        if(iF!=MOParameter::INDEX)
        //        {
        fieldName = getFieldName(iF,Qt::UserRole);
        fieldName.replace(" ",XMLTools::space());
        fieldValue = getFieldValue(iF).toString();
        fieldValue.replace(" ",XMLTools::space());
        cItem.setAttribute(fieldName,fieldValue);
        //        }
    }
    return cItem;
}
Exemplo n.º 24
0
/*!
 *\~english
 *	function check property name, id, header and width.
 *	If have incorrect field name or id, then print message and all.
 *	If have less or more items in DefHeaders or ColWidth, then set them normal.
 *\~russian
 *	Функция проверяет свойства name, id, DefHeaders и ColWidth.
 *	Если находит ошибки в свойствах name или id, она выводит сообщение об этом, но не исправляет ошибки.
 *	Если находит ошибки в свойствах DefHeaders или ColWidth, то исправляет.
 *\~
 */
void
wDBTable::checkFields()
{
	QStringList fl,hl,cl,il;
	unsigned int i;
	QString str;

	//t = getFields(property("tableInd").toInt(),true); //get list fields id
	fl = property("DefFields").toStringList();
	il = property("DefIdList").toStringList();
	cl = property("ColWidth").toStringList();
	hl = property("DefHeaders").toStringList();
//	proverka na nalichie field in metadata
	for(i=0; i<il.count(); i++)
	{
		str = getFieldName(il[i].toInt());
		if(i<fl.count())
		{
			if(str!=fl[i])
			{
				aLog::print(aLog::Debug, QString("wDBTable unknown field name `%1' or (and) id `%1'\n").arg(str).arg(il[i]));
			}
		}
		else il.remove(il.at(i--));
		if(i>=hl.count()) hl << str;
		if(i>=cl.count()) cl << property("DefaultColWidth").toString();
	}
	while(i<hl.count())
	{
		hl.remove(hl.at(i));
	}
	while(i<cl.count())
	{
		cl.remove(cl.at(i));
	}
	setProperty("DefFields", fl );
	setProperty("DefHeaders", hl );
	setProperty("ColWidth", cl );
	setProperty("DefIdList", il );
}
Exemplo n.º 25
0
static void renderExtensionFieldMaybe (int xftype, const tagEntryInfo *const tag, json_t *response)
{
	const char *fname = getFieldName (xftype);

	if (fname && isFieldRenderable (xftype) && isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))
	{
		switch (xftype)
		{
		case FIELD_LINE_NUMBER:
			json_object_set_new (response, fname,
					     json_integer (tag->lineNumber));
			break;
		case FIELD_FILE_SCOPE:
			json_object_set_new (response, fname,
					     json_boolean(1));
			break;
		default:
			json_object_set_new (response, fname,
					     escapeFieldValue (tag, xftype, false));
		}
	}
}
Exemplo n.º 26
0
void PVStructure::fixParentStructure()
{
    PVStructure *parent = getParent();
    if(parent==NULL) return;
    StructureConstPtr parentStructure = parent->structurePtr;
    String fieldName = getFieldName();
    size_t index = parentStructure->getFieldIndex(fieldName);
    StringArray const &fieldNames = parentStructure->getFieldNames();
    size_t num = fieldNames.size();
    FieldConstPtrArray fields(num);
    FieldConstPtrArray const & oldFields = parentStructure->getFields();
    for(size_t i=0; i< num; i++) {
        if(i==index) {
            fields[i] = structurePtr;
        } else {
            fields[i] = oldFields[i];
        }
    }
    FieldConstPtr field = getFieldCreate()->createStructure(
        parentStructure->getID(),fieldNames,fields);
    parent->replaceField(field);
    parent->fixParentStructure();
}
Exemplo n.º 27
0
void storageValid(const mutablebson::Document& doc) {
    auto currElem = doc.root().leftChild();
    while (currElem.ok()) {
        if (currElem.getFieldName() == idFieldName) {
            switch (currElem.getType()) {
                case BSONType::RegEx:
                case BSONType::Array:
                case BSONType::Undefined:
                    uasserted(ErrorCodes::InvalidIdField,
                              str::stream() << "The '_id' value cannot be of type "
                                            << typeName(currElem.getType()));
                default:
                    break;
            }
        }

        // Validate this child element.
        const auto deep = true;
        const uint32_t recursionLevel = 1;
        storageValid(currElem, deep, recursionLevel);

        currElem = currElem.rightSibling();
    }
}
Exemplo n.º 28
0
bool	XBSQLExprList::setTypeNames
	(	XBSQLQuerySet	&querySet
	)
{
	if (expr != 0)
	{
		/* Get the type that the expression will return, and	*/
		/* store this in the query set.				*/
		XBSQL::VType 	vtype	;
		int		length	;
		xbString	eName	;

		if (!expr->getExprType   (vtype )) return false	;
		if (!expr->getExprLength (length)) return false	;

		querySet.setFieldInfo (index,
				       vtype,
				       length, getFieldName (eName)) ;
	}

	/* If this is the last list element then return true, otherwise	*/
	/* continue down the list.					*/
	return	next == 0 ? true : next->setTypeNames (querySet) ;
}
Exemplo n.º 29
0
UpdateNode::ApplyResult UpdateArrayNode::apply(ApplyParams applyParams) const {
    if (!applyParams.pathToCreate->empty()) {
        for (size_t i = 0; i < applyParams.pathToCreate->numParts(); ++i) {
            applyParams.pathTaken->appendPart(applyParams.pathToCreate->getPart(i));
        }
        uasserted(ErrorCodes::BadValue,
                  str::stream() << "The path '" << applyParams.pathTaken->dottedField()
                                << "' must exist in the document in order to apply array updates.");
    }

    uassert(ErrorCodes::BadValue,
            str::stream() << "Cannot apply array updates to non-array element "
                          << applyParams.element.toString(),
            applyParams.element.getType() == BSONType::Array);

    // Construct a map from the array index to the set of updates that should be applied to the
    // array element at that index. We do not apply the updates yet because we need to know how many
    // array elements will be updated in order to know whether to pass 'logBuilder' on to the
    // UpdateNode children.
    std::map<size_t, std::vector<UpdateNode*>> matchingElements;
    size_t i = 0;
    for (auto childElement = applyParams.element.leftChild(); childElement.ok();
         childElement = childElement.rightSibling()) {

        // 'childElement' will always be serialized because no updates have been performed on the
        // array yet, and when we populate an upserted document with equality fields from the query,
        // arrays can only be added in entirety.
        invariant(childElement.hasValue());
        auto arrayElement = childElement.getValue();

        for (const auto& update : _children) {
            if (update.first.empty()) {

                // If the identifier is the empty string (e.g. came from 'a.$[].b'), the update
                // should be applied to all array elements.
                matchingElements[i].push_back(update.second.get());
            } else {
                auto filter = _arrayFilters.find(update.first);
                invariant(filter != _arrayFilters.end());
                if (filter->second->matchesBSONElement(arrayElement)) {
                    matchingElements[i].push_back(update.second.get());
                }
            }
        }

        ++i;
    }

    // If at most one array element will be updated, pass 'logBuilder' to the UpdateNode child when
    // applying it to that element.
    const bool childrenShouldLogThemselves = matchingElements.size() <= 1;

    // Keep track of which array elements were actually modified (non-noop updates) for logging
    // purposes. We only need to keep track of one element, since if more than one element is
    // modified, we log the whole array.
    boost::optional<mutablebson::Element> modifiedElement;
    size_t nModified = 0;

    // Update array elements.
    auto applyResult = ApplyResult::noopResult();
    i = 0;
    for (auto childElement = applyParams.element.leftChild(); childElement.ok();
         childElement = childElement.rightSibling()) {
        auto updates = matchingElements.find(i);
        if (updates != matchingElements.end()) {

            // Merge all of the updates for this array element.
            invariant(updates->second.size() > 0);
            auto mergedChild = updates->second[0];
            FieldRefTempAppend tempAppend(*(applyParams.pathTaken), childElement.getFieldName());
            for (size_t j = 1; j < updates->second.size(); ++j) {

                // Use the cached merge result, if it is available.
                const auto& cachedResult = _mergedChildrenCache[mergedChild][updates->second[j]];
                if (cachedResult.get()) {
                    mergedChild = cachedResult.get();
                    continue;
                }

                // The cached merge result is not available, so perform the merge and cache the
                // result.
                _mergedChildrenCache[mergedChild][updates->second[j]] =
                    UpdateNode::createUpdateNodeByMerging(
                        *mergedChild, *updates->second[j], applyParams.pathTaken.get());
                mergedChild = _mergedChildrenCache[mergedChild][updates->second[j]].get();
            }

            auto childApplyParams = applyParams;
            childApplyParams.element = childElement;
            if (!childrenShouldLogThemselves) {
                childApplyParams.logBuilder = nullptr;
            }

            auto childApplyResult = mergedChild->apply(childApplyParams);

            applyResult.indexesAffected =
                applyResult.indexesAffected || childApplyResult.indexesAffected;
            applyResult.noop = applyResult.noop && childApplyResult.noop;
            if (!childApplyResult.noop) {
                modifiedElement = childElement;
                ++nModified;
            }
        }

        ++i;
    }

    // If no elements match the array filter, report the path to the array itself as modified.
    if (applyParams.modifiedPaths && matchingElements.size() == 0) {
        applyParams.modifiedPaths->keepShortest(*applyParams.pathTaken);
    }

    // If the child updates have not been logged, log the updated array elements.
    if (!childrenShouldLogThemselves && applyParams.logBuilder) {
        if (nModified > 1) {

            // Log the entire array.
            auto logElement = applyParams.logBuilder->getDocument().makeElementWithNewFieldName(
                applyParams.pathTaken->dottedField(), applyParams.element);
            invariant(logElement.ok());
            uassertStatusOK(applyParams.logBuilder->addToSets(logElement));
        } else if (nModified == 1) {

            // Log the modified array element.
            invariant(modifiedElement);
            FieldRefTempAppend tempAppend(*(applyParams.pathTaken),
                                          modifiedElement->getFieldName());
            auto logElement = applyParams.logBuilder->getDocument().makeElementWithNewFieldName(
                applyParams.pathTaken->dottedField(), *modifiedElement);
            invariant(logElement.ok());
            uassertStatusOK(applyParams.logBuilder->addToSets(logElement));
        }
    }

    return applyResult;
}
UpdateNode::ApplyResult RenameNode::apply(ApplyParams applyParams) const {
    // It would make sense to store fromFieldRef and toFieldRef as members during
    // RenameNode::init(), but FieldRef is not copyable.
    auto fromFieldRef = std::make_shared<FieldRef>(_val.fieldName());
    FieldRef toFieldRef(_val.valueStringData());

    mutablebson::Document& document = applyParams.element.getDocument();

    size_t fromIdxFound;
    mutablebson::Element fromElement(document.end());
    auto status =
        pathsupport::findLongestPrefix(*fromFieldRef, document.root(), &fromIdxFound, &fromElement);

    if (!status.isOK() || !fromElement.ok() || fromIdxFound != (fromFieldRef->numParts() - 1)) {
        // We could safely remove this restriction (thereby treating a rename with a non-viable
        // source path as a no-op), but most updates fail on an attempt to update a non-viable path,
        // so we throw an error for consistency.
        if (status == ErrorCodes::PathNotViable) {
            uassertStatusOK(status);
            MONGO_UNREACHABLE;  // The previous uassertStatusOK should always throw.
        }

        // The element we want to rename does not exist. When that happens, we treat the operation
        // as a no-op. The attempted from/to paths are still considered modified.
        if (applyParams.modifiedPaths) {
            applyParams.modifiedPaths->keepShortest(*fromFieldRef);
            applyParams.modifiedPaths->keepShortest(toFieldRef);
        }
        return ApplyResult::noopResult();
    }

    // Renaming through an array is prohibited. Check that our source path does not contain an
    // array. (The element being renamed may be an array, however.)
    for (auto currentElement = fromElement.parent(); currentElement != document.root();
         currentElement = currentElement.parent()) {
        invariant(currentElement.ok());
        if (BSONType::Array == currentElement.getType()) {
            auto idElem = mutablebson::findFirstChildNamed(document.root(), "_id");
            uasserted(ErrorCodes::BadValue,
                      str::stream() << "The source field cannot be an array element, '"
                                    << fromFieldRef->dottedField()
                                    << "' in doc with "
                                    << (idElem.ok() ? idElem.toString() : "no id")
                                    << " has an array field called '"
                                    << currentElement.getFieldName()
                                    << "'");
        }
    }

    // Check that our destination path does not contain an array. (If the rename will overwrite an
    // existing element, that element may be an array. Iff pathToCreate is empty, "element"
    // represents an element that we are going to overwrite.)
    for (auto currentElement = applyParams.pathToCreate->empty() ? applyParams.element.parent()
                                                                 : applyParams.element;
         currentElement != document.root();
         currentElement = currentElement.parent()) {
        invariant(currentElement.ok());
        if (BSONType::Array == currentElement.getType()) {
            auto idElem = mutablebson::findFirstChildNamed(document.root(), "_id");
            uasserted(ErrorCodes::BadValue,
                      str::stream() << "The destination field cannot be an array element, '"
                                    << toFieldRef.dottedField()
                                    << "' in doc with "
                                    << (idElem.ok() ? idElem.toString() : "no id")
                                    << " has an array field called '"
                                    << currentElement.getFieldName()
                                    << "'");
        }
    }

    // Once we've determined that the rename is valid and found the source element, the actual work
    // gets broken out into a $set operation and an $unset operation. Note that, generally, we
    // should call the init() method of a ModifierNode before calling its apply() method, but the
    // init() methods of SetElementNode and UnsetNode don't do anything, so we can skip them.
    SetElementNode setElement(fromElement);
    auto setElementApplyResult = setElement.apply(applyParams);

    ApplyParams unsetParams(applyParams);
    unsetParams.element = fromElement;
    unsetParams.pathToCreate = std::make_shared<FieldRef>();
    unsetParams.pathTaken = fromFieldRef;

    UnsetNode unsetElement;
    auto unsetElementApplyResult = unsetElement.apply(unsetParams);

    // Determine the final result based on the results of the $set and $unset.
    ApplyResult applyResult;
    applyResult.indexesAffected =
        setElementApplyResult.indexesAffected || unsetElementApplyResult.indexesAffected;

    // The $unset would only be a no-op if the source element did not exist, in which case we would
    // have exited early with a no-op result.
    invariant(!unsetElementApplyResult.noop);

    return applyResult;
}