func extractPlatformStringsExprs(expr bzl.Expr) (platformStringsExprs, error) {
	var ps platformStringsExprs
	if expr == nil {
		return ps, nil
	}

	// Break the expression into a sequence of expressions combined with +.
	var parts []bzl.Expr
	for {
		binop, ok := expr.(*bzl.BinaryExpr)
		if !ok {
			parts = append(parts, expr)
			break
		}
		parts = append(parts, binop.Y)
		expr = binop.X
	}

	// Process each part. They may be in any order.
	for _, part := range parts {
		switch part := part.(type) {
		case *bzl.ListExpr:
			if ps.generic != nil {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: multiple list expressions")
			}
			ps.generic = part

		case *bzl.CallExpr:
			x, ok := part.X.(*bzl.Ident)
			if !ok || x.Name != "select" || len(part.List) != 1 {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: callee other than select or wrong number of args")
			}
			arg, ok := part.List[0].(*bzl.DictExpr)
			if !ok {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: select argument not dict")
			}
			var dict **bzl.DictExpr
			for _, item := range arg.List {
				kv := item.(*bzl.KeyValueExpr) // parser guarantees this
				k, ok := kv.Key.(*bzl.StringExpr)
				if !ok {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict keys are not all strings")
				}
				if k.Value == "//conditions:default" {
					continue
				}
				key, err := label.Parse(k.Value)
				if err != nil {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict key is not label: %q", k.Value)
				}
				if KnownOSSet[key.Name] {
					dict = &ps.os
					break
				}
				if KnownArchSet[key.Name] {
					dict = &ps.arch
					break
				}
				osArch := strings.Split(key.Name, "_")
				if len(osArch) != 2 || !KnownOSSet[osArch[0]] || !KnownArchSet[osArch[1]] {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict key contains unknown platform: %q", k.Value)
				}
				dict = &ps.platform
				break
			}
			if dict == nil {
				// We could not identify the dict because it's empty or only contains
				// //conditions:default. We'll call it the platform dict to avoid
				// dropping it.
				dict = &ps.platform
			}
			if *dict != nil {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: multiple selects that are either os-specific, arch-specific, or platform-specific")
			}
			*dict = arg
		}
	}
	return ps, nil
}
func extractPlatformStringsExprs(expr bzl.Expr) (platformStringsExprs, error) {
	var ps platformStringsExprs
	if expr == nil {
		return ps, nil
	}

	
	var parts []bzl.Expr
	for {
		binop, ok := expr.(*bzl.BinaryExpr)
		if !ok {
			parts = append(parts, expr)
			break
		}
		parts = append(parts, binop.Y)
		expr = binop.X
	}

	
	for _, part := range parts {
		switch part := part.(type) {
		case *bzl.ListExpr:
			if ps.generic != nil {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: multiple list expressions")
			}
			ps.generic = part

		case *bzl.CallExpr:
			x, ok := part.X.(*bzl.Ident)
			if !ok || x.Name != "select" || len(part.List) != 1 {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: callee other than select or wrong number of args")
			}
			arg, ok := part.List[0].(*bzl.DictExpr)
			if !ok {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: select argument not dict")
			}
			var dict **bzl.DictExpr
			for _, item := range arg.List {
				kv := item.(*bzl.KeyValueExpr) 
				k, ok := kv.Key.(*bzl.StringExpr)
				if !ok {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict keys are not all strings")
				}
				if k.Value == "
					continue
				}
				key, err := label.Parse(k.Value)
				if err != nil {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict key is not label: %q", k.Value)
				}
				if KnownOSSet[key.Name] {
					dict = &ps.os
					break
				}
				if KnownArchSet[key.Name] {
					dict = &ps.arch
					break
				}
				osArch := strings.Split(key.Name, "_")
				if len(osArch) != 2 || !KnownOSSet[osArch[0]] || !KnownArchSet[osArch[1]] {
					return platformStringsExprs{}, fmt.Errorf("expression could not be matched: dict key contains unknown platform: %q", k.Value)
				}
				dict = &ps.platform
				break
			}
			if dict == nil {
				
				
				
				dict = &ps.platform
			}
			if *dict != nil {
				return platformStringsExprs{}, fmt.Errorf("expression could not be matched: multiple selects that are either os-specific, arch-specific, or platform-specific")
			}
			*dict = arg
		}
	}
	return ps, nil
}
func extractPlatformStringsExprs ( expr bzl . Expr ) ( platformStringsExprs , error ) { var ps platformStringsExprs if expr == nil { return ps , nil } // Break the expression into a sequence of expressions combined with +. var parts [ ] bzl . Expr for { binop , ok := expr . ( * bzl . BinaryExpr ) if ! ok { parts = append ( parts , expr ) break } parts = append ( parts , binop . Y ) expr = binop . X } // Process each part. They may be in any order. for _ , part := range parts { switch part := part . ( type ) { case * bzl . ListExpr : if ps . generic != nil { return platformStringsExprs { } , fmt . Errorf ( " " ) } ps . generic = part case * bzl . CallExpr : x , ok := part . X . ( * bzl . Ident ) if ! ok || x . Name != " " || len ( part . List ) != 1 { return platformStringsExprs { } , fmt . Errorf ( " " ) } arg , ok := part . List [ 0 ] . ( * bzl . DictExpr ) if ! ok { return platformStringsExprs { } , fmt . Errorf ( " " ) } var dict * * bzl . DictExpr for _ , item := range arg . List { kv := item . ( * bzl . KeyValueExpr ) // parser guarantees this k , ok := kv . Key . ( * bzl . StringExpr ) if ! ok { return platformStringsExprs { } , fmt . Errorf ( " " ) } if k . Value == " " { continue } key , err := label . Parse ( k . Value ) if err != nil { return platformStringsExprs { } , fmt . Errorf ( " " , k . Value ) } if KnownOSSet [ key . Name ] { dict = & ps . os break } if KnownArchSet [ key . Name ] { dict = & ps . arch break } osArch := strings . Split ( key . Name , " " ) if len ( osArch ) != 2 || ! KnownOSSet [ osArch [ 0 ] ] || ! KnownArchSet [ osArch [ 1 ] ] { return platformStringsExprs { } , fmt . Errorf ( " " , k . Value ) } dict = & ps . platform break } if dict == nil { // We could not identify the dict because it's empty or only contains // //conditions:default. We'll call it the platform dict to avoid // dropping it. dict = & ps . platform } if * dict != nil { return platformStringsExprs { } , fmt . Errorf ( " " ) } * dict = arg } } return ps , nil }
// extractPlatformStringsExprs matches an expression and attempts to extract
// sub-expressions in platformStringsExprs. The sub-expressions can then be
// merged with corresponding sub-expressions. Any field in the returned
// structure may be nil. An error is returned if the given expression does
// not follow the pattern described by platformStringsExprs.
extractPlatformStringsExprs matches an expression and attempts to extract sub - expressions in platformStringsExprs . The sub - expressions can then be merged with corresponding sub - expressions . Any field in the returned structure may be nil . An error is returned if the given expression does not follow the pattern described by platformStringsExprs .