/** * Creates and returns a rule instance. * * <p>It is the caller's responsibility to add the rule to the package (the caller may choose not * to do so if, for example, the rule has errors). */ static Rule createRule( Package.Builder pkgBuilder, RuleClass ruleClass, BuildLangTypedAttributeValuesMap attributeValues, EventHandler eventHandler, @Nullable FuncallExpression ast, Location location, @Nullable Environment env) throws InvalidRuleException, InterruptedException { Preconditions.checkNotNull(ruleClass); String ruleClassName = ruleClass.getName(); Object nameObject = attributeValues.getAttributeValue("name"); if (nameObject == null) { throw new InvalidRuleException(ruleClassName + " rule has no 'name' attribute"); } else if (!(nameObject instanceof String)) { throw new InvalidRuleException(ruleClassName + " 'name' attribute must be a string"); } String name = (String) nameObject; Label label; try { // Test that this would form a valid label name -- in particular, this // catches cases where Makefile variables $(foo) appear in "name". label = pkgBuilder.createLabel(name); } catch (LabelSyntaxException e) { throw new InvalidRuleException("illegal rule name: " + name + ": " + e.getMessage()); } boolean inWorkspaceFile = pkgBuilder.isWorkspace(); if (ruleClass.getWorkspaceOnly() && !inWorkspaceFile) { throw new RuleFactory.InvalidRuleException( ruleClass + " must be in the WORKSPACE file " + "(used by " + label + ")"); } else if (!ruleClass.getWorkspaceOnly() && inWorkspaceFile) { throw new RuleFactory.InvalidRuleException( ruleClass + " cannot be in the WORKSPACE file " + "(used by " + label + ")"); } AttributesAndLocation generator = generatorAttributesForMacros(attributeValues, env, location, label); try { return ruleClass.createRule( pkgBuilder, label, generator.attributes, eventHandler, ast, generator.location, new AttributeContainer(ruleClass)); } catch (LabelSyntaxException e) { throw new RuleFactory.InvalidRuleException(ruleClass + " " + e.getMessage()); } }
private Package deserializeInternal(InputStream in) throws PackageDeserializationException, IOException, InterruptedException { // Read the initial Package message so we have the data to initialize the builder. We will read // the Targets in individually later. Build.Package packagePb = Build.Package.parseDelimitedFrom(in); Package.Builder builder; try { builder = new Package.Builder( PackageIdentifier.create( packagePb.getRepository(), new PathFragment(packagePb.getName())), null); } catch (LabelSyntaxException e) { throw new PackageDeserializationException(e); } StoredEventHandler eventHandler = new StoredEventHandler(); deserializeInternal(packagePb, eventHandler, builder, in); builder.addEvents(eventHandler.getEvents()); return builder.build(); }
/** * Creates a {@link Rule} instance, adds it to the {@link Package.Builder} and returns it. * * @param pkgBuilder the under-construction {@link Package.Builder} to which the rule belongs * @param ruleClass the {@link RuleClass} of the rule * @param attributeValues a {@link BuildLangTypedAttributeValuesMap} mapping attribute names to * attribute values of build-language type. Each attribute must be defined for this class of * rule, and have a build-language-typed value which can be converted to the appropriate * native type of the attribute (i.e. via {@link BuildType#selectableConvert}). There must be * a map entry for each non-optional attribute of this class of rule. * @param eventHandler a eventHandler on which errors and warnings are reported during rule * creation * @param ast the abstract syntax tree of the rule expression (optional) * @param location the location at which this rule was declared * @param env the lexical environment of the function call which declared this rule (optional) * @throws InvalidRuleException if the rule could not be constructed for any reason (e.g. no * {@code name} attribute is defined) * @throws NameConflictException if the rule's name or output files conflict with others in this * package * @throws InterruptedException if interrupted */ static Rule createAndAddRule( Package.Builder pkgBuilder, RuleClass ruleClass, BuildLangTypedAttributeValuesMap attributeValues, EventHandler eventHandler, @Nullable FuncallExpression ast, Location location, @Nullable Environment env) throws InvalidRuleException, NameConflictException, InterruptedException { Rule rule = createRule(pkgBuilder, ruleClass, attributeValues, eventHandler, ast, location, env); pkgBuilder.addRule(rule); return rule; }
/** * Creates a rule with the attribute values that are already parsed. * * <p><b>WARNING:</b> This assumes that the attribute values here have the right type and bypasses * some sanity checks. If they are of the wrong type, everything will come down burning. */ @SuppressWarnings("unchecked") private static Rule createRuleWithParsedAttributeValues( RuleClass ruleClass, Label label, Package.Builder pkgBuilder, Location ruleLocation, Map<String, ParsedAttributeValue> attributeValues, EventHandler eventHandler, AttributeContainer attributeContainer) throws LabelSyntaxException, InterruptedException { Rule rule = pkgBuilder.newRuleWithLabelAndAttrContainer( label, ruleClass, null, ruleLocation, attributeContainer); rule.checkValidityPredicate(eventHandler); for (Attribute attribute : rule.getRuleClassObject().getAttributes()) { ParsedAttributeValue value = attributeValues.get(attribute.getName()); if (attribute.isMandatory()) { Preconditions.checkState(value != null); } if (value == null) { continue; } rule.setAttributeValue(attribute, value.value, value.explicitlySpecified); ruleClass.checkAllowedValues(rule, attribute, eventHandler); if (attribute.getName().equals("visibility")) { // TODO(bazel-team): Verify that this cast works rule.setVisibility(PackageFactory.getVisibility((List<Label>) value.value)); } } rule.populateOutputFiles(eventHandler, pkgBuilder); Preconditions.checkState(!rule.containsErrors()); return rule; }
/** * Deserialize a package from its representation as a protocol message. The inverse of {@link * PackageSerializer#serialize}. * * @throws IOException * @throws InterruptedException */ private void deserializeInternal( Build.Package packagePb, StoredEventHandler eventHandler, Package.Builder builder, InputStream in) throws PackageDeserializationException, IOException, InterruptedException { Path buildFile = packageDeserializationEnvironment.getPath(packagePb.getBuildFilePath()); Preconditions.checkNotNull(buildFile); DeserializationContext context = new DeserializationContext(builder); builder.setFilename(buildFile); if (packagePb.hasDefaultVisibilitySet() && packagePb.getDefaultVisibilitySet()) { builder.setDefaultVisibility( PackageFactory.getVisibility( deserializeLabels(packagePb.getDefaultVisibilityLabelList()))); } // It's important to do this after setting the default visibility, since that implicitly sets // this bit to true builder.setDefaultVisibilitySet(packagePb.getDefaultVisibilitySet()); if (packagePb.hasDefaultTestonly()) { builder.setDefaultTestonly(packagePb.getDefaultTestonly()); } if (packagePb.hasDefaultDeprecation()) { builder.setDefaultDeprecation(packagePb.getDefaultDeprecation()); } builder.setDefaultCopts(packagePb.getDefaultCoptList()); if (packagePb.hasDefaultHdrsCheck()) { builder.setDefaultHdrsCheck(packagePb.getDefaultHdrsCheck()); } if (packagePb.hasDefaultLicense()) { builder.setDefaultLicense(deserializeLicense(packagePb.getDefaultLicense())); } builder.setDefaultDistribs(deserializeDistribs(packagePb.getDefaultDistribList())); for (String subinclude : packagePb.getSubincludeLabelList()) { Label label = deserializeLabel(subinclude); builder.addSubinclude(label, null); } ImmutableList.Builder<Label> skylarkFileDependencies = ImmutableList.builder(); for (String skylarkFile : packagePb.getSkylarkLabelList()) { skylarkFileDependencies.add(deserializeLabel(skylarkFile)); } builder.setSkylarkFileDependencies(skylarkFileDependencies.build()); MakeEnvironment.Builder makeEnvBuilder = new MakeEnvironment.Builder(); for (Build.MakeVar makeVar : packagePb.getMakeVariableList()) { for (Build.MakeVarBinding binding : makeVar.getBindingList()) { makeEnvBuilder.update( makeVar.getName(), binding.getValue(), binding.getPlatformSetRegexp()); } } builder.setMakeEnv(makeEnvBuilder); for (Build.Event event : packagePb.getEventList()) { deserializeEvent(eventHandler, event); } if (packagePb.hasContainsErrors() && packagePb.getContainsErrors()) { builder.setContainsErrors(); } builder.setWorkspaceName(packagePb.getWorkspaceName()); deserializeTargets(in, context); }